在下面显示的代码中,我使用阻塞调用从套接字接收50个字节的数据并回显它。但是发生的事情是代码在收到一个字节后卡住了。在另一个命令提示符下运行的telnet中连接仍显示为已连接。这可能会遗漏什么?
import socket
import sys
host = ''
port = 8888
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((host,port))
print 'Socket Bind Complete'
s.listen(10)
print 'Now Listening'
while 1:
conn, adr = s.accept()
print 'connected with' + adr[0] + ':' + str(adr[1])
data = conn.recv(50)
print data
if not data:
break
conn.sendall(data)
conn.close()
s.close()
答案 0 :(得分:0)
问题是你每次通过循环accept
新连接,并且只从该连接接收一次。下一次循环,你忘记了那个连接,并accept
一个新连接,阻塞直到其他人连接。
如果您只想处理单个连接并退出,只需将accept
移到循环外:
conn, adr = s.accept()
print 'connected with' + adr[0] + ':' + str(adr[1])
while True:
data = conn.recv(50)
print data
if not data:
break
conn.sendall(data)
conn.close()
s.close()
如果您希望一次处理一个连接,但在完成第一个连接后等待新连接,请添加外部循环。
while True:
conn, adr = s.accept()
print 'connected with' + adr[0] + ':' + str(adr[1])
while True:
data = conn.recv(50)
print data
if not data:
break
conn.sendall(data)
conn.close()
s.close()
如果要像大多数服务器那样一次处理多个连接,则需要某种异步机制 - select
和非阻塞套接字,gevent
,线程等等。例如:
def handle_client(conn, addr):
print 'connected with' + adr[0] + ':' + str(adr[1])
while True:
data = conn.recv(50)
print data
if not data:
break
conn.sendall(data)
conn.close()
client_threads = []
try:
while True:
conn, adr = s.accept()
client_thread = threading.Thread(target=handle_client, args=[conn, addr])
client_thread.start()
client_threads.append(client_thread)
finally:
s.close()
for client_thread in client_threads:
client_thread.join()
在任何这些设计中,您最好使用with
语句而不是明确的close
来电和/或try
/ finally
。