0

我正在编写一个服务器代码来监听来自套接字的信息,但是当我按下字母时,PI 必须向客户端发送一条“消息”。这是我到目前为止所做的:

import select
import Queue
import socket
import time
import sys
import msvcrt
from msvcrt import getch

n = 0
HOST = ''
PORT = 2323

servsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
servsock.bind((HOST, PORT))
servsock.listen(5)
servsock.setblocking(0)

inputs = [servsock]
outputs = []
message_queues = {}

while 1:
    (sread, swrite, serr) =  select.select(inputs, outputs, []);
    for sock in sread:
        if  sock is servsock:
            (newsock, address) = servsock.accept()
            newsock.setblocking(0)
            print "New connection: ", address
            inputs.append(newsock)
            newsock.send("You are connected")
            outputs.append(newsock)

        else:
            recv_msg = sock.recv(100)
            if recv_msg == "":
                (host, port) = sock.getpeername()
                print "Client %s:%s disconnected" % (host,port)
                sock.close()
                inputs.remove(sock)
                outputs.remove(sock)
            else:
                (host, port) = sock.getpeername()
                print "Client %s:%s sent: %s "% (host,port,recv_msg)           

    for sock in swrite:
        while msvcrt.kbhit():
            if msvcrt.getch() == "p":
                sock.send("Message")

但是看起来 select 到达了 swrite,进入了那里,但是它不再在 sread 和 swrite 之间迭代。如果我随时按“1”,它确实会向套接字发送“消息”,但它永远不会返回到 sread!我只需要一直阅读传入的消息,当我按下 P 键发送“消息”时,不会阻塞程序的其余部分。

你能帮我么?谢谢

4

2 回答 2

0

为什么你期望它进入读取段?它应该读什么而不是?换句话说,你怎么知道它没有在它应该到达的时候到达那里?如果没有新的连接或数据发送到这里,则选择将永远不会触发读取,因为没有读取要做。

但是,这段代码并不好,因为您的套接字(几乎)总是可写的,因此您将向 swrite 部分发送垃圾邮件。当你想写东西时,你应该只选择写。如果你检查你的 CPU,你几乎可以保证 100% 的利用率。

理想情况下,您会找到一个库,该库允许您将键盘输入添加为可选对象,以便您可以在选择中查找键盘点击。但是,我不知道是否有办法在 python 中做到这一点。

于 2013-09-13T05:57:14.407 回答
0

您忘记了 select.select 的超时时间,所以它在那里阻塞。这是一个等待长达 100 毫秒(0.1 秒)的示例:

(sread, swrite, serr) =  select.select(inputs, outputs, [], 0.1);
于 2020-05-20T03:26:14.333 回答