我的python套接字服務器偵聽,然後連接到客戶端,然後客戶端將從用戶發送不確定數量的字符串。客戶端可能會關閉或失去與服務器的連接。Python套接字如何處理客戶端意外關閉
這會導致錯誤。
[Errno 10053]建立的連接被主機中的軟件中止。 或 [Errno 10054]現有連接被遠程主機強制關閉
如何處理此事件以便我可以關閉連接並重新啓動偵聽重新連接的服務器?
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客戶端例如:
# 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()
要重現此錯誤,運行在一個命令窗口中的服務器,並且在第二客戶端,然後關閉客戶端窗口。
有處理關閉一個更優雅的方式通過使用'with'進行上下文管理。 (在'socket'模塊的文檔中沒有提到,或者在任何例子中都沒有提到它,但是檢查'socket.socket'的成員確實有'__enter __()'和'__exit __()',因此看起來是有效的上下文管理器,至少在Python 3中。) – JAB
@JAB你能給出一個如何使用'with'的例子嗎? –
@IlanBiala'作爲文件打開(path,'w'):#在縮進塊內對文件進行操作將在寫入模式下打開'path'指定的文件,並在'with'開始的塊被退出後自動關閉它通過成功或失敗的執行。 '__enter __()'/'__exit __()'沒有在'socket'文檔中列出,但存在於源代碼中。 – JAB