【发布时间】:2015-10-05 10:54:36
【问题描述】:
我正在开发一个简单的聊天服务器,将连接的客户端存储在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()
我认为问题在于我如何声明我的套接字,尽管我不确定我是否正确使用了线程。谢谢!
【问题讨论】:
-
你试过打电话给
conn.setblocking(False)吗? -
不应该在handle_new_connection()启动的线程中轮询来自连接的用户输入吗?另外,你不应该在出现 socket.error 异常后调用 handle_new_connection(conn),只有在没有异常时才调用。