我正在开发一个简单的聊天服务器,将连接的客户端存储在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()
我认为问题在于我如何宣布我的套接字,尽管我并不积极,我也正确使用线程。谢谢!
答案 0 :(得分:1)
问题是accept
返回一个新套接字,“最初所有套接字都处于阻塞模式。” (来自https://docs.python.org/2/library/socket.html)。因此,您需要在接受调用返回后立即添加conn.setblocking(0)
。