使用select处理多个请求 [英] Handle multiple requests with select

查看:120
本文介绍了使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆