How do I reconnect a disconnected socket?

J

Jason Kristoff

I'm trying to make something that once it is disconnected will
automatically try to reconnect. I'll add some more features in later so
it doesn't hammer the server but right now I just want to keep it simple
and get that part working. The problem is that when I use sock.close I
get an error message of
Bad File Descriptor
and if I either use shutdown or just go straight to reconnecting I get:
Transport endpoint is already connected

This is what I've got right now:

#! /usr/bin/env python
import socket, string
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def doconn():
sock.connect(("localhost", 1234))
def dodiscon():
sock.close()
doconn()

doconn()

while (1):
buffer = sock.recv(1024)
if not buffer:
dodiscon()
 
L

Laszlo Nagy

This is what I've got right now:

#! /usr/bin/env python
import socket, string
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def doconn():
sock.connect(("localhost", 1234))
def dodiscon():
sock.close()
doconn()

doconn()

while (1):
buffer = sock.recv(1024)
if not buffer:
dodiscon()

sock.recv(1024) can return zero bytes of data indicating that no data
arrived yet. It does not mean that you have been disconnected. This is
especially true when you do nothing but recv, recv, recv() in an
infinite loop.

I recommend that you use select.select to see if there is some data that
can be read. Call socket.recv() only when you know that it will not fail.

Best,

Laszlo
 
G

Grant Edwards

sock.recv(1024) can return zero bytes of data indicating that no data
arrived yet.

No, it can't.
It does not mean that you have been disconnected.

Yes, that is exactly what it means.

From the recv() man page:

RETURN VALUE
These calls return the number of bytes received, or -1 if an error
occurred. The return value will be 0 when the peer has performed an
orderly shutdown.
 
L

Laszlo Nagy

Yes, that is exactly what it means.


RETURN VALUE
These calls return the number of bytes received, or -1 if an error
occurred. The return value will be 0 when the peer has performed an
orderly shutdown.
Mea cupla. :)

What about non-blocking sockets?
 
G

Grant Edwards

Mea cupla. :)

What about non-blocking sockets?

$ man recv
....
If no messages are available at the socket, the receive
calls wait for a message to arrive, unless the socket is
non-blocking (see fcntl(2)), in which case the value -1
is returned and the external variable errno set to
EAGAIN.
....
 
M

Mike

I'm trying to make something that once it is disconnected will
automatically try to reconnect. I'll add some more features in later so
it doesn't hammer the server but right now I just want to keep it simple
and get that part working. The problem is that when I use sock.close I
get an error message of
Bad File Descriptor
and if I either use shutdown or just go straight to reconnecting I get:
Transport endpoint is already connected

This is what I've got right now:

#! /usr/bin/env python
import socket, string
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def doconn():
sock.connect(("localhost", 1234))
def dodiscon():
sock.close()
doconn()

doconn()

while (1):
buffer = sock.recv(1024)
if not buffer:
dodiscon()

I'd recommend to look at Twisted ReconnectingClientFactory -
http://twistedmatrix.com/trac/browser/trunk/twisted/internet/protocol.py#L198
 
B

Bryan Olson

Grant said:
$ man recv
...
If no messages are available at the socket, the receive
calls wait for a message to arrive, unless the socket is
non-blocking (see fcntl(2)), in which case the value -1
is returned and the external variable errno set to
EAGAIN.

As Grant showed, a successful recv() returning zero bytes
indicates the end of the data stream from the remote peer.
Other cases block or raise errors.

A few more notes:

When a socket will return zero bytes to indicate the end of the
data stream, it will select() as readable.

In the case Laszlo asked about here -- a non-blocking socket
is not shutdown but no data is immediately readable -- on some
systems, the error is EWOULDBLOCK, which may be, but is not
generally, the same code as EAGAIN. (There may be yet other
systems that have different error conventions; I don't know.)

The Python library's 'errno' module exports the error names with
their associated numeric values.

Python's socket module does not 'return' these error codes; it
raises exceptions. A non-blocking socket, or equivalently a
socket with a timeout of zero, will raise socket.error. The
errno in the exception's (errno, string) value should be
EAGAIN or EWOULDBLOCK. If a socket has a non-zero timeout,
and that timeout expires, the operation raises socket.timeout.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top