i am facing the following problem. Me and a friend of mine, have set up a wireless network using uhf data modem. When i am trying to send a file (e.g. photo) and the connection is ok there is no problem. But when i am trying to send a file and for some reason there is no connection for a while, the form freezes until there is a reestablishment. Can anyone help me please? Here is the code i use from both server and client side (Delphi 2010).
Client Side (Transmits file [this form freezes if connection is lost for a while or permanently]):
procedure TForm17.BtnSendFile(Sender: TObject);
var
FS: TFileStream;
filename: string;
begin
filetotx := 'temp.jpg';
FS := TFileStream.Create(filetotx, fmOpenRead, fmShareDenyWrite);
FS.Position := 0;
try
Form1.IdTCPClient1.Socket.LargeStream := true;
Form1.IdTCPClient1.Socket.WriteLn('PIC');
Form1.IdTCPClient1.Socket.Write(FS, 0, true);
finally
FS.Free;
end;
end;
Server Side (receives file)
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
s, filename:string;
FS: TFileStream;
Jpg: TJpegImage;
begin
S := AContext.Connection.Socket.ReadLn;
if S = 'PIC' then
begin
filename := 'PIC_' + datetostr(date) + ' ' + timetostr(time) + '.jpg';
filename := StringReplace(filename, '/', '-', [rfReplaceAll]);
filename := StringReplace(filename, ':', '_', [rfReplaceAll]);
filename := extractfilepath(Application.exename) + 'PIC\' + filename;
FS := TFileStream.Create(filename, fmCreate);
FS.Position := 0;
AContext.Connection.Socket.LargeStream := true;
AContext.Connection.Socket.ReadStream(FS);
Jpg := TJpegImage.Create;
FS.Position := 0;
Jpg.LoadFromStream(FS);
form26.image1.Picture.Assign(Jpg);
try
Jpg.Free;
FS.Free;
finally
//send feedback file received
AContext.Connection.Socket.WriteLn('PICOK');
TIdNotify.NotifyMethod(form26.Show);
end;
end;
Client Side (receives feedback 'PICOK')
type
TReadingThread = class(TThread)
protected
FConn: TIdTCPConnection;
procedure Execute; override;
procedure DoTerminate; override;
public
constructor Create(AConn: TIdTCPConnection); reintroduce;
end;
constructor TReadingThread.Create(AConn: TIdTCPConnection);
begin
TLog.AddMsg('Client Thread Created');
FConn := AConn;
inherited Create(False);
end;
procedure TReadingThread.Execute;
begin
while not Terminated do
begin
if S='MSGOK' then
.
.
else if S = 'PICOK' then
begin
Do Something
end
end;
end;
procedure TReadingThread.DoTerminate;
begin
TLog.AddMsg('Disconnected');
inherited;
end;
Your client code is sending the file in the context of the main UI thread. That is why the UI freezes - there are no messages being processed while the send is busy. Either move that code into a worker thread (preferred), or else drop a
TIdAntiFreezecomponent onto your Form.Your server code is fine as far as the actual file transfer is concerned, however your
try/finallyblock is wrong, and you are directly accessing aTImagewithout synchronizing with the main UI thread. You are already synchronizing when callingform26.Show, you just need to synchronize when callingform26.image1.Picture.Assign(Jpg)as well. Try this instead:Or this: