Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Tcp disconnect detection

Tags:

python

tcp

I have a simpletcp example:

import socket
import time


TCP_IP = '127.0.0.1'
TCP_PORT = 81
BUFFER_SIZE = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

while True:
    s.send(bytes('hello', 'UTF-8'))
    time.sleep(1)

s.close()

How can I detect, if I lost the connection to the server, and how can I safely reconnect then?

Is it necessary to wait for answer to the server?

UPDATE:

import socket
import time

TCP_IP = '127.0.0.1'
TCP_PORT = 81
BUFFER_SIZE = 1024

def reconnect():
    toBreak = False
    while True:
        s.close()
        try:
            s.connect((TCP_IP, TCP_PORT))
            toBreak = True
        except:
            print ("except")        
        if toBreak:
            break
        time.sleep(1)


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

while True:
    try:    
        s.send(bytes('hello', 'UTF-8'))
        print ("sent hello")
    except socket.error as e:
        reconnect()

    time.sleep(1)

s.close()

If I break the connection, it raises an error (does not really matter what), and goes to the reconnect loop. But after I restore the connection, the connect gives back this error:

OSError: [WinError 10038] An operation was attempted on something that is not a socket

If I restart the script, which calls the same s.connect((TCP_IP, TCP_PORT)), it works fine.

like image 964
András Kovács Avatar asked Jan 09 '14 18:01

András Kovács


People also ask

How do I disconnect a TCP connection in python?

If you want to close the connection in a timely fashion, call shutdown() before close().

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

How do you check socket is connected or not? 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.


2 Answers

You'll get a socket.error:[Errno 104] Connection reset by peer exception (aka ECONNRESET) on any call to send() or recv() if the connection has been lost or disconnected. So to detect that, just catch that exception:

while True:
    try:
        s.send(bytes('hello', 'UTF-8'))
    except socket.error, e:
        if e.errno == errno.ECONNRESET:
            # Handle disconnection -- close & reopen socket etc.
        else:
            # Other error, re-raise
            raise
    time.sleep(1)
like image 140
Adam Rosenfield Avatar answered Oct 10 '22 11:10

Adam Rosenfield


Use a new socket when you attempt to reconnect.

def connect():
    while True:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((host, port))
            return s.makefile('w')
        except socket.error as e:
            log("socket error {} reconnecting".format(e))
            time.sleep(5)

dest = connect()
while True:
    line = p.stdout.readline()
    try:
        dest.write(line)
        dest.flush()
    except socket.error as e:
        log("socket error {} reconnecting".format(e))
        dest = connect()
like image 25
jrwren Avatar answered Oct 10 '22 11:10

jrwren