How to send TCP RST (Reset) packet ?
-
wrote on 10 Jul 2012, 04:07 last edited by
Hello
I'm working on a project where I need to send a TCP RST packet to a device.
Background information:
I currently use a QTcpSocket object to communicate over TCP between the desktop (where my app runs) and a device (iOS device)..
When the desktop's needs to terminate the communication with the device. What I currently do is simply call QTcpSocket::disconnectFromHost(), then QTcpSocket::close().
Unfortunately, when doing so, the device doesn't detect the connection has been interrupted and conitnues to send data (it sends data over two UDP streams).The documentation states that for the iOS device to disconnect, it needs to receive a TCP Reset packet?
Now, how do I do that using the Qt framework?
Thank you in advance..
Jean-Yves -
wrote on 10 Jul 2012, 07:50 last edited by
What do two UDP streams have to do with a TCP connection?
-
wrote on 10 Jul 2012, 09:56 last edited by
Sounds like a setup where you have a control channel over TCP, and two data channels over UDP. Perhaps a video and an audio stream. Not all that weird, right?
On the actual question: no idea, sorry.
-
wrote on 10 Jul 2012, 10:36 last edited by
Don't know if you can do this directly from Qt classes, but setting SO_LINGER on socket with TIME_OUT=0 should immediately reset and hard close the socket.
-
wrote on 10 Jul 2012, 14:32 last edited by
- Immediately after close() or shutdown() of course
-
wrote on 10 Jul 2012, 21:55 last edited by
[quote author="Andre" date="1341914199"]Sounds like a setup where you have a control channel over TCP, and two data channels over UDP. Perhaps a video and an audio stream. Not all that weird, right?
On the actual question: no idea, sorry.[/quote]
Exactly that setup..
Pretty common really.I only commented on the UDP setup for providing some background information, it's not really relevant to the actual question.
-
wrote on 10 Jul 2012, 21:58 last edited by
[quote author="AcerExtensa" date="1341916590"]Don't know if you can do this directly from Qt classes, but setting SO_LINGER on socket with TIME_OUT=0 should immediately reset and hard close the socket.[/quote]
Yes, I am aware of SO_LINGER, but this only work with BSD type socket. That won't work on Windows for example, SO_LINGER appears broken here.
But obviously, I'm using Qt, so I was hoping Qt offered such API
-
wrote on 10 Jul 2012, 22:33 last edited by
There are several ways to perform an orderly release of a TCP connection: none of them involve the RST flag AFAICT. RST is used to abort a connection so I suggest you try QAbstractSocket::abort() to see what that buys you.
-
wrote on 11 Jul 2012, 09:13 last edited by
[quote author="ChrisW67" date="1341959608"]There are several ways to perform an orderly release of a TCP connection: none of them involve the RST flag AFAICT. RST is used to abort a connection so I suggest you try QAbstractSocket::abort() to see what that buys you.[/quote]
I tried that.
From what I can tell, from a TCP perspective there's no difference between abort or disconnectFromHost. They both close the socket in the same manner.
It only makes a difference for Qt with how it deals with the internal pending data to be sent on the socket.
The other thing I've been unable to manage with Qt are half-open state sockets.
Eg. the Qt application sends a termination command, and while the remote hasn't sent a FIN packet back yet, Qt will stop being able to read on the socket. Theoretically, the connection shouldn't be closed until the remote has sent another FIN back.I'm doing my tests on mac OS... As far as I can tell, Qt TCP sockets aren't really by the book there. It probably doesn't make any different for 99.9% of the user, but it matters to my usage of it.
-
wrote on 11 Jul 2012, 16:13 last edited by
The TCP RST is ment to use in those cases where a serverport is not open in order to receive a connection or if a partner wants to close the connection with an immediate abort discarding any data that was queued to be sent. Try to use a network sniffer to see what actually is happening on your wire:
"wireshark":http://www.wireshark.org/
"paketyzer":http://sourceforge.net/projects/packetyzer/
"MS Network Monitor":http://www.microsoft.com/en-us/download/details.aspx?id=4865 (espec. win7/64Bit) -
wrote on 12 Jul 2012, 00:11 last edited by
[quote author="franku" date="1342023213"]The TCP RST is ment to use in those cases where a serverport is not open in order to receive a connection or if a partner wants to close the connection with an immediate abort discarding any data that was queued to be sent. Try to use a network sniffer to see what actually is happening on your wire:
[/quote]And how do you think I figured out I needed to send a TCP RST to the device to start with? I am using a network analyser
with Qt, a connection is closed as follow currently (this is the same if you use abort(), close(), disconnectFromHost():
Qt:[FIN,ACK]
Device:[ACK]From that point on, Qt has closed everything, and do not listen to anything coming from the host, it never acknowledges the FIN from the device
It happens that the device expect the following the FIN sent by the Qt app:
Device: [PSH,ACK]
Qt: [ACK]
Device: [FIN,ACK]
Qt: [ACK]
and only then should Qt close the receiving end of the socket -
wrote on 12 Jul 2012, 08:21 last edited by
You will have to provide a minimal example that demonstrates the problem and tell us which platform is displaying the behaviour.
This is the sequence of events for the Qt Fortune Client example (port 49823) talking to a non-Qt netcat server (port 49152) on Linux. The close sequence is quite normal when the client's Quit button is pressed.
@
TCP: 49823 > 49152 [SYN] Seq=0
TCP: 49152 > 49823 [SYN, ACK] Seq=0 Ack=1
TCP: 49823 > 49152 [ACK] Seq=1 Ack=1TCP: 49823 > 49152 [FIN, ACK] Seq=1 Ack=1 // client advises it is finished
TCP: 49152 > 49823 [FIN, ACK] Seq=1 Ack=2 // server ACKs the client FIN and closes its end
TCP: 49823 > 49152 [ACK] Seq=2 Ack=2 // client ACKs the FIN from the server
@ -
wrote on 12 Jul 2012, 09:22 last edited by
bq. And how do you think I figured out I needed to send a TCP RST to the device to start with?
I thought you were referencing a software manual. We are all here to help you, not to point at you. I do not yet understand what currently the host and what the device is and why one of them absolutely needs a RST. So a better description of platforms is very appreciated.
1/13