Recent

Author Topic: Lnet TCP sendmessage, 2 packages merged into 1  (Read 1308 times)

senglit

  • Full Member
  • ***
  • Posts: 141
Lnet TCP sendmessage, 2 packages merged into 1
« on: May 12, 2020, 07:09:22 am »
Hi, all

I got a problem when I used Lnet.

I had codes like these in TCP Server side:
Code: Pascal  [Select][+][-]
  1. Svr.SendMessage('a'+Chr(9)+'b'+Chr(9)+'c',Svr.Iterator);
  2. ...
  3. Svr.SendMessage('e'+Chr(9)+'f'+Chr(9)+'g',Svr.Iterator);
  4.  

On Client side, I had code like thes
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ClntReceive(aSocket: TLSocket);
  2. var
  3.   s:string;
  4. begin
  5.   if aSocket.GetMessage(s)>0 then begin
  6.   ...
  7.   end;
  8. end;
  9.  

The message can be transferred from Server to Client. But sometimes(not always), the ClntReceive is called and I get the s as
Code: Pascal  [Select][+][-]
  1.  'a'+Chr(9)+'b'+Chr(9)+'c'+'e'+Chr(9)+'f'+Chr(9)+'g'

But what I want is that this procedure to be triggered twice and give me 2 strings seperately. How to do it?
I use Win11 + Lazarus3.6 + FPC Trunk. fpcupdeluxe

ccrause

  • Hero Member
  • *****
  • Posts: 1117
Re: Lnet TCP sendmessage, 2 packages merged into 1
« Reply #1 on: May 12, 2020, 09:09:26 am »
AFAIKS Svr.SendMessage takes a string and send it as a stream of characters.  The SendMessage and GetMessage handlers to not implement anything to interpret a stream of characters as Pascal strings.  You have to define your own protocol on top of this if you want to transfer complete string entities.  Note that another behaviour you can see is that a long string gets broken up into separate chunks, so your GetMessage handler have to cater for this possibility too.  It could be as simple as appending a special character (which then cannot be used as part of your message itself) such as CR or LF or both on the server side to delimit the end of a string, then on the client side you save the received data in a buffer, scan from the start of the buffer for the special delimiter. Once delimiter is found, move data from start to just before delimiter to your final string.

For a robust implementation consider the following cases in your code:
* A string gets chopped up into several fragments
* A string can be transferred as a complete packet (message)
* A packet (message) can contain a string + a fragment of or more than one string

I'm sure there are other TCP/IP components that implement this type of functionality but I haven't done any TCP/IP programming in a very long time.

Maybe slightly easier is to implement a ping-pong protocol where the server sends a string + delimiter then wait for the client to acknowledge the message before sending the next message.

There are probably lots of ways to implement this, perhaps you should tell us a bit more about your requirements.

PS:
Code: Pascal  [Select][+][-]
  1. Svr.SendMessage('a'+Chr(9)+'b'+Chr(9)+'c',Svr.Iterator);
can alternatively be written as:
Code: Pascal  [Select][+][-]
  1. Svr.SendMessage('a'#9'b'#9'c',Svr.Iterator);

senglit

  • Full Member
  • ***
  • Posts: 141
Re: Lnet TCP sendmessage, 2 packages merged into 1
« Reply #2 on: May 14, 2020, 07:05:34 am »
Thanks for your reply. After I found this problem, I tried to build a receiving pool on Client side and it works. But I've thought that maybe there is a simple way to set the Lnet components to ensure each string can be received completely and seperately, so I posted this topic.

According to your explaination, that's impossible. You helped me to understand the impossibility and I need to enstrong my user-level protocal. And I do not need to waste time on my old idea.

Thank you!
I use Win11 + Lazarus3.6 + FPC Trunk. fpcupdeluxe

 

TinyPortal © 2005-2018