|
|
Home » Community » Newbie corner » TcpSocket, Know when distant connection have been closed
TcpSocket, Know when distant connection have been closed [message #57216] |
Sat, 12 June 2021 17:10  |
 |
Xemuth
Messages: 387 Registered: August 2018 Location: France
|
Senior Member |
|
|
Hello U++ !
I'm programming an application which rely on TcpSocket and Json sending & receiving.
A web server ask for data via a JSON command and I send him a formatted JSON. Here is how I do it :
while(!d_stopThread && !d_activeConnection.IsError() && d_activeConnection.IsOpen()){
if(d_activeConnection.WaitRead()){
Upp::String data;
while(d_activeConnection.Peek()!= -1){
data << char(d_activeConnection.Get());
}
if(data.GetCount() > 0){
Upp::String sendingCmd = "";
LLOG("[Server][Listener] Receiving from web server: " + data.Left(20));
sendingCmd = d_callbackServer(d_socket, data);
if(sendingCmd.GetCount() > 0){
LLOG("[Server][Listener] Sending to web server: " + sendingCmd.Left(20));
d_activeConnection.Put(sendingCmd + "\n\0");
}
}
}else{
if(d_activeConnection.GetSOCKET() == -1)
break;
else
Sleep(100);
}
}
if(d_activeConnection.IsError()) LLOG("[Server][Listener] WebServer error: " + d_socket.GetErrorDesc());
d_activeConnection.Clear();
LLOG("[Server][Listener] WebServer disconnected");
The web server send me data in JSON, I retrieve this data then I send back a json with the requested data. Here are a wireshark screenshot :

So here is my question, how to know when the distant socket have been closed ? I have trying many things but
either it's me who cuts the connection (probably because of a timeout or erro during WaitRead())
either I don't detect the FIN from the server side and dont react so my connection never reset
[Updated on: Sat, 12 June 2021 19:17] Report message to a moderator
|
|
|
|
|
|
|
Re: TcpSocket receiving ghost data [message #57221 is a reply to message #57216] |
Sat, 12 June 2021 18:48   |
Oblivion
Messages: 1204 Registered: August 2007
|
Senior Contributor |
|
|
One more thing (general recommendation for anyone reading this topic, not directed specifically at you):
You seem to have the assumption -or that's my impression- that GetLine() will always work on JSON formatted text.
If so, this is a false assumption. GetLine() is a convenience method for retrieving strictly formated texts which have line breaks. For this reason:
1) It cannot be effectively used with raw binary data, because it will always eat bytes '\r' (0xd) and '\n' (0xa).
2) Json (or XML) is not requred to have line breaks. That is optional and purely for cosmetics.
In fact line breaks in JSON/XML are not welcomed on networking circles because of the unnecessary overhead they add. (Think about it: A JSON with 1024 lines with linebreaks will add 1024 bytes to the document to be transferred)
3) My suggestion. Send the string length first thant retrieve the text, using TcpSocket::Get(length) method.
Best regards,
Oblivion
Github page: https://github.com/ismail-yilmaz
upp-components: https://github.com/ismail-yilmaz/upp-components
Bobcat the terminal emulator: https://github.com/ismail-yilmaz/Bobcat
[Updated on: Sat, 12 June 2021 19:10] Report message to a moderator
|
|
|
|
Re: TcpSocket receiving ghost data [message #57223 is a reply to message #57222] |
Sat, 12 June 2021 20:03   |
Oblivion
Messages: 1204 Registered: August 2007
|
Senior Contributor |
|
|
Hello Xemuth,
Quote:
So here is my question, how to know when the distant socket have been closed ? I have trying many things but
either it's me who cuts the connection (probably because of a timeout or erro during WaitRead())
either I don't detect the FIN from the server side and dont react so my connection never reset
Hard to say without knowing the transactions between S/C but I suspect that remote server may have enabled SO_LINGER.
Otherwise, AFAIK, IsEof() or IsError() should return true, depending on the server.
See: https://man7.org/linux/man-pages/man7/socket.7.html
SO_LINGER
Sets or gets the SO_LINGER option. The argument is a
linger structure.
struct linger {
int l_onoff; /* linger active */
int l_linger; /* how many seconds to linger for */
};
When enabled, a close(2) or shutdown(2) will not return
until all queued messages for the socket have been
successfully sent or the linger timeout has been reached.
Otherwise, the call returns immediately and the closing is
done in the background. When the socket is closed as part
of exit(2), it always lingers in the background.
In general, the "polite" way in networking is to let the client close its connection to the server (after it is done with transactions.). But this is more a recommendation not a strict rule.
Best regards,
Oblivion
Github page: https://github.com/ismail-yilmaz
upp-components: https://github.com/ismail-yilmaz/upp-components
Bobcat the terminal emulator: https://github.com/ismail-yilmaz/Bobcat
[Updated on: Sat, 12 June 2021 20:28] Report message to a moderator
|
|
|
|
Goto Forum:
Current Time: Mon Apr 28 16:48:40 CEST 2025
Total time taken to generate the page: 0.00764 seconds
|
|
|