You are making a classic newbie mistake of mismatching the WriteStream() and ReadStream() calls. By default, WriteStream() DOES NOT send the stream size, but the parameter values you are passing to ReadStream() tell it to expect the stream size.
Other mistakes you are making:
You are calling ReadStream() in a loop, but not calling WriteStream() in a loop.
Wrapping your entire OnExecute code in a critical section. Don't do that.
Wrapping your entire OnExecute code in a try/except that swallows all exceptions. DO NOT swallow EIdException-derived exceptions. TIdTCPServer needs to handle them.
Calling ShowMessage(). It is not thread-safe. Use Windows.MessageBox() instead.
Using write buffering with WriteStream(). That is a huge waste of memory for large files. Get rid of that.
Update: try this:
Server:
begin
InputString := AThread.Connection.ReadLn;
if InputString = 'PIC' then begin
AFullFileName := FFilePath + 'PIC01.jpg';
AFileStream := TFileStream.Create(AFullFileName, fmOpenRead or fmShareDenyNone);
try
AThread.Connection.WriteStream(AFileStream, True, True);
finally
AFileStream.Free;
end;
end;
AThread.Connection.Disconnect;
end;
Client:
begin
if IdTCPClient.Connected then IdTCPClient.Disconnect;
IdTCPClient.Host := '127.0.0.1';
IdTCPClient.Port := 2018;
if FileExists(FFilePath + 'PIC01.jpg') then
DeleteFile(FFilePath + 'PIC01.jpg');
AFileStream := TFileStream.Create(FFilePath + 'PIC01.jpg', fmCreate);
try
try
IdTCPClient.Connect;
try
IdTCPClient.WriteLn('PIC');
IdTCPClient.ReadStream(AFileStream, -1, False);
finally
IdTCPClient.Disconnect;
end;
finally
AFileStream.Free;
end;
except
DeleteFile(FFilePath + 'PIC01.jpg');
end;
end;