简体   繁体   中英

Python sockets how to handle the client closing unexpectedly

My python socket server listens and then connects to a client that will then send a indeterminate number of strings from a user. The client may then close or lose connection to the server.

This causes an error.

[Errno 10053] An established connection was aborted by the software in your host machine. or [Errno 10054] An existing connection was forcibly closed by the remote host

How do I handle this event so that I can close the connection and restart my server listening for a reconnect?

Python Server example:

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 7001              # Arbitrary non-privileged port
s = None

def startListening():
    print "starting to listen"

    for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                                  socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
        af, socktype, proto, canonname, sa = res
        try:
            s = socket.socket(af, socktype, proto)
        except socket.error as msg:
            s = None
            continue
        try:
            s.bind(sa)
            s.listen(1)
        except socket.error as msg:
            s.close()
            s = None
            continue
        break
    if s is None:
        print 'could not open socket'
        sys.exit(1)
    conn, addr = s.accept()
    print 'Connected by', addr
    while 1:
        data = conn.recv(1024)
        if not data: 
            break
        print data
        message = ""
        while not "quit" in message:
            message = raw_input('Say Something : ')
            conn.sendall(message)
        #conn.send("I got that, over!")

    conn.close()
    print "connection closed"

while 1:
    startListening()

python client example:

# Echo client program
import socket
import sys

HOST = 'localhost'    # The remote host
PORT = 7001              # The same port as used by the server
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except socket.error as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
s.sendall("Please send me some strings")
data = ""
while ("quit" not in data):
    data = s.recv(1024)
    print 'Received', repr(data)
s.close()

To reproduce this error, run the server in one command window and the client in a second, then close the client window.

Adding try: except: around the data send and data recv in the server script appears to mitigate the problem:

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 7001              # Arbitrary non-privileged port
s = None

def startListening():
    print "starting to listen"

    for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                                  socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
        af, socktype, proto, canonname, sa = res
        try:
            s = socket.socket(af, socktype, proto)
        except socket.error as msg:
            s = None
            continue
        try:
            s.bind(sa)
            s.listen(1)
        except socket.error as msg:
            s.close()
            s = None
            continue
        break
    if s is None:
        print 'could not open socket'
        sys.exit(1)
    conn, addr = s.accept()
    print 'Connected by', addr
    while 1:
        try: 
            data = conn.recv(1024)
        except:
            print "cannot recieve data"
            break
        if not data: 
            break
        print data
        message = ""
        while not "quit" in message:
            message = raw_input('Say Something : ')
            try: 
                conn.sendall(message)
            except Exception as exc:
                #print exc # or something.
                print "message could not be sent"
                break
        #conn.send("I got that, over!")

    conn.close()
    print "connection closed"

while 1:
    startListening()

Simply close your side of the connection and be ready to accept a new connection again.

The best way to handle this is to separate the creation of the server socket and the accept/read/write loop:

create_server_socket()
while True:
    accept_new_connection();
    try:
        read_request();
        write_response()
    finally:
        close_connection()

我认为,当客户端意外关闭时,根据SIGPIPE,您应该处理信号

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM