Solved

Indy TcpClient and TcpServer

Posted on 2002-07-19
17
2,503 Views
Last Modified: 2008-03-10
I have problems because i would really like an event on the TcpClient that would get fired when a new message arived. But there is not a event for that, The Server has the onExecute event wich works well, but when i send message to client there need to be an timer that checks like:
Msg := IdTCPClient1.ReadLn;

But then i thought that the events that client have, OnWork, OnBeginWork, OnEndWork could be used, my plan was to send a stringstream from server, the help also says that the OnBeginWork will get fired if u use SendStream(), but it just isn't.

I gues the only way is to do the stream stuff, but i am just not sure how. Someone said that the client events need to be assigned first? hmm

Well hope someone can help me on this, i am requesting a normal event on the tcpclient like the OnRead that the TClientsocket have.

Thanks.
Dennis
0
Comment
Question by:Dennis9
  • 9
  • 8
17 Comments
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7166772
you need to check for new data constantly
you could create a new thread that checks for new data periodically
here's my implementation of a thread that checks for new data with TidTCPClient
http://lee.nover.has.his.evilside.org/isapi/pas2html.dll/pas2html?File=/delphi/MiscFiles/vn_common/lnVidTypes.pas

find the TCommThread implementation (at the end of the page)
0
 
LVL 1

Author Comment

by:Dennis9
ID: 7167031
Lee_Nover -> can u not explain a bit more on how you would do so? I don't totally understand you.

Ask if u need more information on my problem.

Dennis
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7167141
well if you take a look at my TCommThread  Class then there is not much to say

you could simply make a descendant of TlnThread, override the Run method and in it do smth like:
Msg:=TCP.ReadLn;
if Msg <> '' then
begin
  // handle the message
end;

it would be best if Msg was a global var in the new thread
for synchronizing I use SendMessage
if you still need more explaining I'll write an example :)
0
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 
LVL 1

Author Comment

by:Dennis9
ID: 7167198
well for 200 points i almost expect a sample :)

Dennis
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7167272
:)
the thing is you got the whole code .. almost
well I'll make that example for you :)
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7167389
ok I've made an example for you
here's the complete project :
http://lee.nover.has.his.evilside.org/isapi/pas2html.dll/pas2html?File=/delphi/projects/TlnThreadSubclassing

this is the basic idea how to use the TlnThread class
it can be very usefull for things like communication
if you need more help just ask
0
 
LVL 1

Author Comment

by:Dennis9
ID: 7167564
it seems like your server is down at the moment but i will just wait then :)
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7167582
sorry bout that
some kids been playing arround with dosnets !!!
0
 
LVL 1

Author Comment

by:Dennis9
ID: 7167620
i am very impressed about your code, it also works pretty well :)

But i am having problems receveing to the that the server sends in the connect event. Ok let me explain it a bit more.

Client connect.
Server send some text back in the OnConnect event.

But the client app does not receive it all, first when i send back a line using client it receive the text send from the servers onceonnect event. I don't know if its possible to fix this, if not i am happy enough about the code i have now.

Thanks Lee_Nover
0
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 200 total points
ID: 7167689
aha I know this problem
I have it also !!!
it's due to the buffer not being full yet and Indy TCP won't send the message until the buffer is full
I really havne't overcome this problem though it seems very easy too
I tried setting the buffer size to the length of the message, i does help a bit but not always
I also use WriteBuffer with WriteNow set to TRUE
you could try sending the text like this:

uses IdTCPConnection, IdGlobal;
function SendLineNow(TCP: TIdTCPConnection; const Text: string): Boolean;
begin
     try
        TCP.WriteBuffer(PChar(Text + EOL)^, Length(Text + EOL), true); // true to send the buffer immediatelly
        Result:=true;
     except
        Result:=false;
     end;
end;

usage:

procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
     SendLineNow(AThread.Connection, 'Hello user from ' + AThread.Connection.Socket.Binding.IP);
end;


about the code .. hehe tnx :)

hope it helps

0
 
LVL 1

Author Comment

by:Dennis9
ID: 7167698
yup your SendLineNow procedure seemed to fix my problem.
Thank you very mutch again, u been a big help :)

If i get into more problems wih this socket i hope u will be there.

See u around Lee_Nover
0
 
LVL 1

Author Comment

by:Dennis9
ID: 7199181
Lee_Nover -> have u found a way to fix the send crap?

If i put a button on client that sends some text to server, and press it 5 times. server will only receive half of it why?

Maybe u can help.

Thanks

dennis
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7199307
don't know how you implemented it
did you use the Queue method as in my TCommThread ?
if you have all the text should go through
to queue the text takes a fraction of the time it takes to send it
that's why I queue the commands, and send them 'later'
0
 
LVL 1

Author Comment

by:Dennis9
ID: 7200996
I just used your client thread code. Does more need to be done
?
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7201213
hum .. I don't have such problems
do you use QueueCommand method ?
0
 
LVL 1

Author Comment

by:Dennis9
ID: 7201431
what do u mean ? use the QueueCommand ?
I have not seen anything named QueueCommand. Can u not tell more about it?
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7201668
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question