Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: detect when a socket disconnects for any reason?

Tags:

I'm writing an app in Python 2.7.5 using the raw socket interface (import socket).

I need to know if there's a way I can either register some sort of event, or easily test at a regular interval, if a TCP socket connection is still connected and established.

Most of the advice I've found says things like "just try to read from it; if it's closed you'll get an error or no bytes." However, sometimes I'm not ready to read from it but I still want to know if the socket gets closed, so for example I can manually reconnect immediately.

Also, reading from the socket would remove the bytes read from the buffer, so reading simply to test for connection "liveness" doesn't seem feasible.

Having a background thread to check for connection liveness would be OK with me. That thread could check say once per second to see if the connection is live; if it is dropped, then it could call a function, or set a variable or some other thing so that the app knows the connection closed. Knowing WHY it closed (reset by peer, timeout, etc) would be even more useful....

Any advice on this?

like image 518
fdmillion Avatar asked Jun 30 '13 02:06

fdmillion


People also ask

How do you check if a socket is connected disconnected in Python?

If you need to determine the current state of the connection, make a nonblocking, zero-byte Send call. If the call returns successfully or throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.

How can I tell when a socket is closed on the other end?

The most obvious way to accomplish this is having that process call read on the socket for a connection and check whether read returns 0 (i.e. reads zero bytes from the socket), in which case we know that the connection has been closed.

How do you stop a listening socket in Python?

To close the connection, break the while loop. Garbage collection will remove the thread or process but join will ensure none get left behind. Persistent sockets close when the user closes them or they timeout.

Do you need to close socket Python?

It is only ever necessary to shutdown a socket for writing if (1) you have forked the process and definitely want to send the FIN now, or (2) you are engaging in a mutual read-to-EOS protocol such that both peers close at the same time. Otherwise close() is sufficient. The Python documentation should be corrected.


1 Answers

Use select like this tutorial suggested http://docs.python.org/3/howto/sockets.html#non-blocking-sockets

If a socket is in the output readable list, you can be as-close-to-certain-as-we-ever-get-in-this-business that a recv on that socket will return something. Same idea for the writable list. You’ll be able to send something. Maybe not all you want to, but something is better than nothing. (Actually, any reasonably healthy socket will return as writable - it just means outbound network buffer space is available.)

... if somewhere in those input lists of sockets is one which has died a nasty death, the select will fail.

(The last paragraph is no longer there in the Python 3 version.)

This is the flow I usually use

import select import socket  ip = '127.0.0.1' port = 80  conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect((ip, port))  while True:     try:         ready_to_read, ready_to_write, in_error = \             select.select([conn,], [conn,], [], 5)     except select.error:         conn.shutdown(2)    # 0 = done receiving, 1 = done sending, 2 = both         conn.close()         # connection error event here, maybe reconnect         print('connection error')         break     if len(ready_to_read) > 0:         recv = conn.recv(2048)         # do stuff with received data         print(f'received: {recv}')     if len(ready_to_write) > 0:         # connection established, send some stuff         conn.send('some stuff') 
like image 55
Steve Zhan Avatar answered Oct 20 '22 06:10

Steve Zhan