从套接字收到一个字节后代码卡住了吗?

时间:2013-05-28 08:05:17

标签: python sockets

在下面显示的代码中,我使用阻塞调用从套接字接收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() 

1 个答案:

答案 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