i have a Python test program for testing features of another software component, let's call the latter the component under test (COT).
The Python test program is connected to the COT via a persistent TCP connection.
The Python program is using the Python socket API for this.
Now in order to simulate a failure of the physical link, I'd like to have the Python program shut the socket down, but without disconnecting appropriately.
I.e. i don't want anything to be sent on the TCP channel any more, including any TCP SYN
/ACK
/FIN
. I just want the socket to go silent. It must not respond to the remote packets any more.
This is not as easy as it seems, since calling close
on a socket will send TCP FIN
packets to the remote end. (graceful disconnection).
So how can i kill the socket without sending any packets out?
I cannot shut down the Python program itself, because it needs to maintain other connections to other components. For information, the socket runs in a separate thread. So i thought of abruptly killing the thread, but this is also not so easy. (Is there any way to kill a Thread in Python?)
Any ideas?
close() is indeed the correct way to close the connection.
One way or another, if you don't close a socket, your program will leak a file descriptor. Programs can usually only open a limited number of file descriptors, so if this happens a lot, it may turn into a problem.
Strictly speaking, you're supposed to use shutdown on a socket before you close it. The shutdown is an advisory to the socket at the other end. Depending on the argument you pass it, it can mean “I'm not going to send anymore, but I'll still listen”, or “I'm not listening, good riddance!”.
close() call shuts down the socket associated with the socket descriptor socket, and frees resources allocated to the socket. If socket refers to an open TCP connection, the connection is closed. If a stream socket is closed when there is input data queued, the TCP connection is reset rather than being cleanly closed.
You can't do that from a userland process since in-kernel network stack still holds resources and state related to given TCP connection. Event if you kill your whole process the kernel is going to send a FIN
to the other side since it knows what file descriptors your process had and will try to clean them up properly.
One way to get around this is to engage firewall software (on local or intermediate machine). Call a script that tells the firewall to drop all packets from/to given IP and port (that of course would need appropriate administrative privileges).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With