BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

how use TIdTCPClient in thread?

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Internet Winsock
View previous topic :: View next topic  
Author Message
Jorge Woo
Guest





PostPosted: Tue Dec 14, 2004 2:34 am    Post subject: how use TIdTCPClient in thread? Reply with quote



i add a TIdTCPClient in Form,and creat a Thread, run the TIdTCPClient`s
ReadStream`s method in thread,but sometime,it lost respond.
anyone can give a example to show how use TIdTCPClient in thread?


Back to top
Martin James
Guest





PostPosted: Wed Dec 15, 2004 8:40 am    Post subject: Re: how use TIdTCPClient in thread? Reply with quote




"Jorge Woo" <hugeant (AT) 126 (DOT) com> wrote

Quote:
i add a TIdTCPClient in Form,and creat a Thread, run the TIdTCPClient`s
ReadStream`s method in thread,but sometime,it lost respond.
anyone can give a example to show how use TIdTCPClient in thread?

Can you post some code? Especially the TThread.execute, TThread constructor
and details of any inter-thread comms, eg synchronize or postMessage.

Basically, I create the TidTCPClient in the constructor of the thread,
passing hostname, port etc. as thread constructor parameters. I load up the
properties of the TidTCPClient and resume the thread. The execute method
just calls whatever methods of TidTCPClient you want. I rarely use streams,
but there/s no reason why you should not create, say, a TfileStream & load
data into it with TidTCPClient.

I have some demp stuff but it does not use Tstream.

Rgds,
Martin






** Form **
procedure TfoCthread.FormCreate(Sender: TObject);
var newPort:integer;
begin
try
newPort:=strToInt(ebPort.text); // Set socket data in thread
except
newPort:=9010;
ebPort.text:='9010';
end;
if (ebIPaddr.text='') then ebIPaddr.text:='localhost';
myClientThread:=TIndyRx.create(self.handle,ebIPaddr.text,newPort);
setTimeouts; // can be done anytime - just sets integers in thread fields
myClientThread.resume; //go!
end;

** Thread **
TIndyRx = class(TThread)
private
FIPaddr:string;
FPort:integer;
outMess:pTitcRecord;
protected
procedure Execute; override;
procedure sendMessToForm;
procedure indySockStatus(ASender: TObject; const AStatus: TIdStatus;
const AStatusText: String);
procedure indySockDisconnected(Sender: TObject);
procedure indySockConnected(Sender: TObject);
public
formHandle:HWND;
indySock:TidTCPclient;
connectWait:TsimpleEvent;
retryTimeout:integer;
readTimeout:integer;
property IPaddr:string read FIPaddr;
procedure setServerSocket(newIP:string;newPort:integer);
property port:integer read FPort;
constructor create(commsHandle:HWND;IPaddr:string;port:integer);
end;


** Thread constructor **
constructor TIndyRx.create(commsHandle:HWND;IPaddr:string;port:integer);
begin
inherited create(true); // suspended to allow creation of stuff b4 run
new(outMess); // get a TitcRecord, ready for first message
freeOnTerminate:=true; // die on your own
indySock:=TidTCPclient.create(nil); // We'll have one of those!
connectWait:=TsimpleEvent.create; // wait on this between connect attempts
with IndySock do
begin
onStatus:=indySockStatus; // load Indy event handlers
onConnected:=indySockConnected;
onDisconnected:=indySockDisconnected;
end;
FIPaddr:=IPaddr; // load Indy socket params
Fport:=port;
readTimeout:=60000; // & some default timeouts
retryTimeout:=4000;
formHandle:=commsHandle; // handle to send messages to
end;

** Thread execute **

procedure TIndyRx.Execute;

procedure handleConnection;
var bytesStillToRead:integer;
bytesToRead:integer;
begin
try
repeat
try
begin
bytesStillToRead:=IndySock.readFromStack(true,INFINITE,true);
while(bytesStillToRead>0) do
begin
if (bytesStillToRead>255) then bytesToRead:=255
else
bytesToRead:=bytesStillToRead;
IndySock.readBuffer(outMess^.data[1],bytesToRead);
outMess^.data[0]:=char(bytesToRead);
if (outMess^.data='') then raise EIdReadTimeout.Create('Readln
timed out');
outMess^.command:=tmData;
sendMessToForm; // and send them to form
dec(bytesStillToRead,bytesToRead);
end;
end;
except
on e:EIdReadTimeout do // send mess to fire readTimeout event
begin
outMess^.command:=tmReadTimeout;
outMess^.data:=e.message;
sendMessToForm;
end;
on e:EIdConnClosedGracefully do // obvious..
begin
exit;
end;
on e:exception do // else send messag to fire error event
begin
outMess^.command:=tmError;
outMess^.data:=e.message;
sendMessToForm;
exit;
end;
end;
until terminated;
finally
indySock.Disconnect;
indySockDisconnected(self); // however we exit, ensure this is fired!
end;
end;

function attemptConnect:boolean;
begin
indySock.host:=FIPaddr; //reload server socket params, in case changed
indySock.Port:=Fport;
try
indySock.Connect(10000); // try...
result:=true; // OK!
except
on e:exception do
begin
result:=false;
outMess^.command:=tmError; // else send error message
outMess^.data:=e.message;
sendMessToForm;
end;
end;
end;

begin
try // keep trying to connect & handle data
repeat
if (attemptConnect) then handleConnection else
connectWait.WaitFor(retryTimeout);
connectWait.ResetEvent;
until terminated;
finally
connectWait.free;
indySock.free; // done!
end;
end;





Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Internet Winsock All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.