I want to send some (big) files over an internet connection at the maximum possible speed, using Indy TCP. I have writen a simple app to test how Indy TCP Client-Server connection works.
What I discovered is that:
- all writes to the socket happens instantly
- even if
Disconnect
after I write, the data is still received on the other side, if it is read - the data can have any size; I wrote 100 MB and I received every bit.
So it means that there is a transmission buffer on the socket that is writen to. And it looks like it can have any size... If I write a large amount of data (let's say 100 MB), I think it is not transmited in a single operation, but in small chuncks (let's say 1 MB). So, as the data is transmitted, that buffer shrinks until it reaches zero, when all data is transmitted. What I need is the length of that buffer at any time, to know when it needs to be filled, so I cand write continuously without thaking up the whole computer memory.
I don't know if what I wrote here makes sense... If not, please tell me to delete the question and ask a more general question. What I want in the end, is to send a file through a Indy TCP connection at the highest speed possible (meaning asynchronous), but with a progress bar and a cancel button.
This is the test app:
procedure TClient.Execute;
var Cmd: Cardinal;
Txt: String;
Buff: TIdBytes;
Size: Integer;
begin
Size:= 5000000;
SetLength(Buff, Size);
Buff[0]:= 33;
Buff[Size-1]:= 55;
Client.Connect;
Cmd:= 1234;
Client.Socket.Write(Cmd);
Client.Socket.Write(Size);
Client.Socket.Write(Buff);
Txt:= 'client finished transmision';
SendMessage(RWnd, WM_USER, WPARAM(@Txt), 0);
Client.Disconnect;
Txt:= 'client disconected';
SendMessage(RWnd, WM_USER, WPARAM(@Txt), 0);
end;
procedure TForm1.ServerExecute(AContext: TIdContext);
var Cmd: Cardinal;
Mess: String;
Buff: TIdBytes;
Size: Integer;
begin
Mess:= 'Server ready';
SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);
Cmd:= AContext.Connection.Socket.ReadUInt32;
Mess:= 'Server receive command';
SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);
if Cmd = 1234 then begin
Size:= AContext.Connection.Socket.ReadInt32;
Sleep(4000);
Mess:= 'Server start reading';
SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);
AContext.Connection.Socket.ReadBytes(Buff, Size);
Mess:= IntToStr(Buff[0]) + ' / ' + IntToStr(Buff[Size-1]);
SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);
end;
Mess:= 'Server closed connection';
SendMessage(Handle, WM_USER, WPARAM(@Mess), 0);
end;