使用select处理多个请求 [英] Handle multiple requests with select
问题描述
目前,我正在从事聊天服务器/客户端项目. 我正在努力使用select处理多个请求,我的服务器脚本使用了select模块,但客户端脚本却没有.结果是,每当用户输入消息时,其他客户端就必须编写自己的消息才能阅读对话.我在网上搜索了很多示例,但是只能用sys.stdin找到代码片段,这不是我想要的.
currently I am working on a chat server/client project. I am struggling with handling multiple requests with select, my server script uses the select module but the client script doesn't. The result is that when ever a user enters message the other clients have to write their own message to read through the conversation. I have searched a lot in the web for examples, but could only find code snippets with sys.stdin which isn't what I want.
我很高兴收到任何说明/解释.
I would glad to receive any instruction/explanation.
服务器代码:
import socket
import select
server_socket = socket.socket()
server_socket.bind(("0.0.0.0", 2855))
server_socket.listen(1)
open_client_sockets = [] # current clients handler
messages_to_send = [] # future message send handler
def send_waiting_messages(wlist):
for message in messages_to_send:
(client_socket, data) = message
if client_socket in wlist: # if current socket in iteration has reading abilities
client_socket.send(data)
messages_to_send.remove(message) # remove from future send handler
def broadcast_message(sock, message):
for socket in open_client_sockets:
if socket != server_socket and socket != sock:
socket.send(message)
while True:
rlist, wlist, xlist = select.select([server_socket] + open_client_sockets, open_client_sockets, []) # apending reading n writing socket to list
for current_socket in rlist: # sockets that can be read
if current_socket is server_socket: # if there is a new client
(new_socket, address) = server_socket.accept()
open_client_sockets.append(new_socket) # clients list
else:
data = current_socket.recv(1024)
if len(data) == 0:
open_client_sockets.remove(current_socket) # remove user if he quit.
print "Connection with client closed."
send_waiting_messages(wlist) # send message to specfic client
else:
broadcast_message(current_socket, "\r" + '<' + data + '> ')
# send_waiting_messages(wlist) # send message to specfic client
server_socket.close()
客户代码:
import socket
import msvcrt
client_socket = socket.socket()
client_socket.connect(("127.0.0.1", 2855))
data = ""
def read_message():
msg = ""
while True:
if msvcrt.kbhit():
key = msvcrt.getch()
if key == '\r': # Enter key
break
else:
msg = msg + "" + key
return msg
while data != "quit":
data = read_message()
client_socket.send(data)
data = client_socket.recv(1024)
print data
client_socket.close()
推荐答案
我的服务器脚本使用选择模块,但客户端脚本不使用.
my server script uses the select module but the client script doesn't.
一种解决方案是在客户端中也使用select
.不幸的是,在Windows上,select
无法处理sys.stdin
,但是我们可以使用 timeout 参数来轮询键盘.
A solution is to use select
also in the client. On Windows unfortunately select
does not handle sys.stdin
, but we can use the timeout argument to poll the keyboard.
import socket
import select
import msvcrt
client_socket = socket.socket()
client_socket.connect(("localhost", 2855))
msg = ""
while True:
ready = select.select([client_socket], [], [], .1)
if client_socket in ready[0]:
data = client_socket.recv(1024)
print data, ' '*(len(msg)-len(data))
print msg,
if msvcrt.kbhit():
key = msvcrt.getche()
if key == '\r': # Enter key
if msg == "quit":
break
client_socket.send(msg)
msg = ""
print
else:
msg = msg + "" + key
client_socket.close()
这篇关于使用select处理多个请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!