views:

122

answers:

2

Hi, is there any way to send a simple text(string value) without using WriteLN and ReadLN?
The ReadLn function needs LF char and when I'm sending a text message via winsock to Indy, ReadLn cannot get the message correctly and some exceptions will be happen continuously.

+1  A: 

Does your text have any termination character? If it does, then you can set ATerminator parameter of ReadLn, so that instead of LF character, it will terminate reading when it reaches your own defined termination character.

If there is no defined termination character, but you know the maximum length of the text, you can set AMaxLineLength parameter of ReadLn. That will cause ReadLn to accept only text with length less than AMaxLineLength.

If there is no defined termination character, and you do not know the maximum length of received text, you can use ReadStream with its AReadUntilDisconnect parameter set to True, instead of using ReadLn. Of course ReadStream reads the data as a stream of bytes. You can assign a TStringStream to it, so that you can have the received bytes as string. AReadUntilDisconnect parameter tells ReadStream to continue reading received data until the client disconnects. So if you set this parameter, your client should disconnect as soon as the text is sent to server.

vcldeveloper
Thank you , when i'm using ReadStream with AReadUntilDisconnect parameter set to True , my client needs to get a response from server(with ReadLn) so i can't close the connection .
Kermia
@vcldeveloper: if you know the string's full length ahead of time, use ReadString() instead of ReadLn(). If you use the AMaxLineLength parameter of ReadLn(), and the client does not send that many characters, then ReadLn() will be blocked waiting for data that never arrives.
Remy Lebeau - TeamB
@Remy Lebeau, thanks for the comment.
vcldeveloper
+2  A: 

If you don't wish to use a termination character (WriteLn/ReadLn do it this way), then write the number of bytes you wish to send first to the socket, and then write out, or read that many bytes on the other side. You could also use a different termination character than newline, which you have duly pulled out of a hat. Perhaps Chr(251), that's a nice one.

In the end, I'll bet you go back to WriteLn/ReadLn. Because it's simple, expected, and it works.

Warren P
*In the end, I'll bet you go back to WriteLn/ReadLn. Because it's simple, expected, and it works.*As i said , when i'm using ReadLn on the server , if an unknown client(for example winsock) send a message without LF char , some exceptions will be happen continuously !see ! in visual basic we were using 'SendData' and 'GetData' methods that we could send any string values without specify LF char and length of data .now i expect do this via indy .Thank you
Kermia
From what I've read, there was no guarantee that GetData would read exactly what a single call to SendData wrote. Multiple calls to SendData might be grouped into a single block of data. Sounds like you were just lucky if that never happened to you, Kermia. The bottom line is that the sender and receiver need to *cooperate* by using a common *protocol*. If the receiver shouldn't read *everything*, then it needs to know when to stop, either by being told how many bytes to expect, or by recognizing a special data sequence that means "stop reading." ReadLn is fine as long as you also use WriteLn.
Rob Kennedy
@Kermia: regarding the continos exceptions, you are not handling the disconnects correctly. What you describe can only happen if your server code is wrapping its reading in a try/except block that is discarding all exceptions that are caught. Do not discard any of Indy's own EIdException-derived exceptions. If you catch them, then re-throw them and let the server process them internally.
Remy Lebeau - TeamB
Thank you Mr Lebeau ! I didn't know 'try/except' is sometimes murderer :D ! my problem solved .
Kermia