5

i am studying asynchronous sockets right now and i have this code:

#!/usr/bin/env python 

""" 
An echo server that uses select to handle multiple clients at a time. 
Entering any line of input at the terminal will exit the server. 
""" 

import select 
import socket 
import sys 

host = 'localhost' 
port = 900 
backlog = 5 
size = 1024 
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
server.bind((host,port)) 
server.listen(backlog) 
input = [server,sys.stdin] 
running = 1 
while running: 
    inputready,outputready,exceptready = select.select(input,[],[]) 

    for s in inputready: 

        if s == server: 
            # handle the server socket 
            client, address = server.accept() 
            input.append(client) 

        elif s == sys.stdin: 
            # handle standard input 
            junk = sys.stdin.readline() 
            running = 0 

        else: 
            # handle all other sockets 
            data = s.recv(size) 
            if data: 
                s.send(data) 
            else: 
                s.close() 
                input.remove(s) 
server.close()

It shoud be a basic kind of echo server using select(), but when I run it, I ger select error 10038 - attemp to manipulation with something which is not socket. Can someone tell me what is wrong? Thank you:)

4

3 回答 3

6

你在 Windows 上工作,不是吗?在 Windows 上,选择仅适用于套接字。但是 sys.stdin 不是套接字。从第 15 行删除它,它应该可以工作。

在 Linux 或类似设备上,我希望它可以按照上面列出的方式工作。

于 2012-08-30T10:35:52.450 回答
4

我以前解决过一个非常相似的问题。

您可以做的是在自己的线程中运行异步循环,并在用户输入内容时将主线程.put数据放入 aQueue.queue中。每次循环时,您都可以检查队列中是否有任何内容。如果确实如此,您将对其采取行动,在您的情况下,通过设置running=0.

如果你这样做,你需要给 select 一个足够短的超时来响应用户输入,比如 0.01 秒。不要对超时的使用感到反感,这就是 Twisted 的 Win32 选择反应器处理这个问题的方式。

仅供参考,在 Unix 系统上,这种事情要容易一百万倍,在那里您可以选择的不仅仅是套接字。我相信在 Windows 上select系统调用是由 Winsock 提供的。在 Unix 上,您可以选择带有文件描述符的任何内容。

如果您需要更多说明,请告诉我。

编辑:你也可以看看multiprocessing.pipe

于 2013-06-24T01:29:12.787 回答
2

关于文档,正确的交互方式select

ready_to_read, ready_to_write, in_error = select.select(potential_readers,
                                                        potential_writers,
                                                        potential_errs,
                                                        timeout)

在你的代码中,

input = [server,sys.stdin] 

sys.stdin不是套接字(而是文件描述符)。

于 2012-08-30T10:27:41.743 回答