Python套接字如何处理客户端意外关闭
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16915023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python sockets how to handle the client closing unexpectedly
提问by Zac
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.
我的 python 套接字服务器侦听然后连接到一个客户端,然后该客户端将从用户发送不确定数量的字符串。然后客户端可能会关闭或失去与服务器的连接。
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
[Errno 10053] 已建立的连接被主机中的软件中止。或 [Errno 10054] 远程主机强行关闭现有连接
How do I handle this event so that I can close the connection and restart my server listening for a reconnect?
如何处理此事件以便关闭连接并重新启动服务器以侦听重新连接?
Python Server example:
Python 服务器示例:
# 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:
python客户端示例:
# 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.
要重现此错误,请在一个命令窗口中运行服务器,然后在一秒钟内运行客户端,然后关闭客户端窗口。
回答by Some programmer dude
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()
回答by Some programmer dude
I think when client is closed unexpectedly, that according to SIGPIPE you should handle the signal
我认为当客户端意外关闭时,根据 SIGPIPE 您应该处理信号
回答by Zac
Adding try: except: around the data send and data recv in the server script appears to mitigate the problem:
在服务器脚本中添加 try: except: 围绕数据发送和数据接收似乎可以缓解问题:
# 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()

