Newsgroups : Borland : borland.public.delphi.internet.winsock : 2005 Feb : Problem : IdTcpCmdServer Hangs while IdTcpCmdClient is waiting for an reponse...
| Subject: | Problem : IdTcpCmdServer Hangs while IdTcpCmdClient is waiting for an reponse... |
| Posted by: | "Stephane Wierzbicki" (swierzbic..@fermoba.fr) |
| Date: | Tue, 22 Feb 2005 17:19:25 |
Hello,
I have a small problem (thanx to remi lebeau who helps me a lot). I want to
send a file from a client to a server. The client need to knwow if the file
has been succefully sended and saved to the server side.
I'm using Indy10 comps (last csv updates)
On the form there is :
1 IdTcpCMDServer
1 IdTcpCMDClient
1 IdServerIOHandlerStack
1 IdIOHandlerStack
1 SaveDialog
1 Button
When I click on the button, I choose a file to send to the server.
The IdTCPCmdCLient use the 'FILE' command (from server) to send the file.
Sending is working well, file is correctly created. It freeze after that (or
seems to).
When Debugging and puting a breakpoint on the File 'CommandHandler', I can
do step by step until the end of the
Command Handling.... then it goes to the IDThread.Execute and block here :
while not Stopped do begin
try
Run; //**** STOP HERE ****
except
on E: Exception do begin
if not HandleRunException(E) then begin
Terminate;
raise;
end;
end;
end;
end;
For info, here is my project sources :
Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPServer,
IdCmdTCPServer,IdContext,
IdTCPConnection, IdTCPClient,IdCommandHandlers,
StdCtrls,IdIOHandler,idstreamvcl,
IdCmdTCPClient, IdServerIOHandler, IdServerIOHandlerSocket,
IdServerIOHandlerStack, IdIOHandlerSocket, IdIOHandlerStack,
IdCustomTCPServer,IdReplyRFC, ExtCtrls, IdStreamVCLWin32;
type
TForm1 = class(TForm)
lboxResults: TListBox;
IdCmdTCPClient1: TIdCmdTCPClient;
IdIOHandlerStack1: TIdIOHandlerStack;
Button2: TButton;
SaveDialog1: TSaveDialog;
IdCmdTCPServer1: TIdCmdTCPServer;
IdServerIOHandlerStack1: TIdServerIOHandlerStack;
procedure Button2Click(Sender: TObject);
procedure IdCmdTCPServer1FILECommand(ASender: TIdCommand);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
var
LWrapper : TIdStreamVCL;
FileStream: TFileStream;
LStreamSize : int64;
Begin
IdCmdTCPClient1.Connect;
IdCmdTCPClient1.GetResponse('200');
if SAveDialog1.execute then
Begin
Button2.Enabled := False;
try
FileStream:= TFileStream.Create(SaveDialog1.filename,fmOpenRead or
fmShareDenyWrite);
try
LWrapper := TIdStreamVCL.Create(FileStream);
try
if IdCmdTCPClient1.SendCmd('FILE'+'|'+ SaveDialog1.filename
+'|'+IntToStr(LWrapper.VCLStream.Size)) <> 100 then
begin
// handle the error in SendCmd() as needed...
ShowMessage(IdCmdTCPClient1.LastCmdResult.Text.Text);
end else
begin
IdCmdTCPClient1.IOHandler.Write(LWrapper,0);
//*********** Block Here ************************
if IdCmdTCPClient1.GetResponse([]) <> 100 then
begin
// handle the error in GetResponse() as needed...
ShowMessage(IdCmdTCPClient1.LastCmdResult.Text.Text);
end;
End;
finally
FreeAndNil(LWrapper);
end;
finally
FreeAndNil(FileStream);
end;
except
on E: Exception do
begin
// handle an unexpected error...
ShowMessage(E.Message);
end;
end;
IdCmdTCPClient1.disconnect;
Button2.Enabled := true;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
try
if IdCmdTCPServer1.Active = false then
IdCmdTCPServer1.Active:=true;
finally end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
try
if IdCmdTCPServer1.Active = true then
IdCmdTCPServer1.Active:=false;
finally end;
end;
procedure TForm1.IdCmdTCPServer1FILECommand(ASender: TIdCommand);
var
LStreamSize : int64;
LWrapper : TIdStreamVCL;
FileStream: TFileStream;
FileName: string;
LReply: TIdReplyRFC;
begin
if ASender.Params.Count <> 2 then
begin
ASender.Reply.SetReply(500, 'wrong number of arguments');
Exit;
end;
try
LStreamSize := StrToInt(ASender.Params[1]);
except
ASender.Reply.SetReply(500, 'invalid parameter');
Exit;
end;
try
FileStream := TFileStream.Create('c:\' +
ExtractFileName(ASender.Params[0]), fmCreate);
try
LWrapper := TIdStreamVCL.Create(FileStream);
try
LReply := TIdReplyRFC.Create(nil);
try
LReply.SetReply(100, 'ready to receive file');
ASender.Context.Connection.IOHandler.Write(LReply.FormattedReply);
finally
FreeAndNil(LReply);
end;
ASender.Context.Connection.IOHandler.ReadStream(LWrapper,
LStreamSize);
ASender.Reply.SetReply(100, 'file received');
finally
FreeAndNil(LWrapper);
end;
finally
FreeAndNil(FileStream);
end;
except
on E: exception do
Begin
ASender.Reply.SetReply(500, E.Message);
end;
end;
end;
end.