为什么这个socket.recv()阻塞?

时间:2015-10-05 02:36:10

标签: python sockets blocking

我正在开发一个简单的聊天服务器,将连接的客户端存储在dict中。我将阻塞设置为false,但在轮询用户输入时似乎一切都在阻止。

我可以与一个客户端连接,服务器显示它将成功接收和广播消息,但当另一个客户端尝试连接时,它不能直到第一个用户"摇动它"提交另一条消息。

server.py

import socket
import time
import threading

def handle_new_connection(connection):
    def handle_t():
        while 1:
            connection.send("Please enter desired username:  ")
            try:
                username = connection.recv(256)
                if username in connections:
                    connection.send("Username taken.")
                elif username:
                    connections[username] = connection
                    connection.send('Welcome to chat, ' + username)
                    print (username + ' has entered chat.')
                    return
            except socket.error as e:
                print e
                break
    handle = threading.Thread(target=handle_t, args=())
    handle.daemon = False
    handle.start()

def broadcast(sender, message):
    print 'Broadcasting:  ' + message
    for username, conn in connections.items():
        if username != sender:
            try:
                conn.send(''.join((sender, ": ", message)).encode('utf-8'))
            except socket.error as e:
                print e
                pass

serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.setblocking(False)
serverSocket.bind(('', 55555))
serverSocket.listen(5)

connections = {}

print 'Booting Server...'

while 1:
    try:
        while 1:
            try:
                conn, addr = serverSocket.accept()
                print ("New Incoming Connection")
            except socket.error as e:
                break
            handle_new_connection(conn)

        for user, conn in connections.items():
            print 'polling for ' + user
            try:
                raw_data = conn.recv(256) # <-- HANGING HERE
                data = raw_data.decode('utf-8')
            except socket.error as e:
                continue

            if data:
                print data
                broadcast(user, data)
            else:
                del connections[user]
                broadcast(user, 'left chat. ' + str(len(connections)) + ' users.')
                print user + " left chat. " + str(len(connections)) + " users."
    except (SystemExit, KeyboardInterrupt):
        break

print 'Closing Server Socket...'
serverSocket.close()    
exit()

我在另一个终端中使用以下脚本进行连接。

client.py

import socket
import threading

def create_sender():
    def sender_t():
        while 1:
            try:
                while 1:
                    try:
                        data = raw_input()
                        clientsocket.send(data.encode('utf-8'))
                    except socket.error as e:
                        break
                    except (SystemExit, KeyboardInterrupt):
                        break
            except (SystemExit, KeyboardInterrupt):
                break

    send = threading.Thread(target=sender_t, args=())
    send.start()

clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('', 55555))
clientsocket.setblocking(False)
print 'Connected to server.'

create_sender()
while 1:
    try:
        while 1:
            try:
                msg = clientsocket.recv(256).decode('utf-8')
                print msg
            except socket.error as e:
                break

    except (SystemExit, KeyboardInterrupt):
        break

clientsocket.close()

我认为问题在于我如何宣布我的套接字,尽管我并不积极,我也正确使用线程。谢谢!

1 个答案:

答案 0 :(得分:1)

问题是accept返回一个新套接字,“最初所有套接字都处于阻塞模式。” (来自https://docs.python.org/2/library/socket.html)。因此,您需要在接受调用返回后立即添加conn.setblocking(0)