繁体   English   中英

Python select 与 sockets 和 sys.stdin

[英]Python select with sockets and sys.stdin

我是 Python 编程的新手,我正在尝试创建服务器和客户端。 我仍然希望能够从键盘上输入一些东西,这样我就可以通过输入“exit”从服务器上关闭服务器。 我已经从各个站点获取示例代码,以了解我在套接字编程和此代码中所处的位置。

但是,每当我运行代码时,都会收到以下错误消息:

The host name of this machine is 127.0.0.1
The IP address of the host is 127.0.0.1
Server now awaiting client connection on port 2836
im right before the select
Traceback (most recent call last):
  File "/root/Server_2.py", line 42, in <module>
    inputready, outputready, exceptready = select.select(input, [], [])
TypeError: argument must be an int, or have a fileno() method.
>>> 

我正在阅读,要通过这个(在 Windows 中)是删除 sys.stdin,因为 Windows 只接受 sockets。我试图在 Linux 中编写这段代码。我尝试了各种方法来尝试获取它去工作,我已经没有资源和想法可以尝试了。 下面是服务器代码:

import socket                       #import socket module
import select
import sys

host = "127.0.0.1"
print ("The host name of this machine is " + host)
hostIP = socket.gethostbyname(host)    # get host IP address
print ("The IP address of the host is %s" % (hostIP)) 
port = 2836                        # Reserve the port for the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((hostIP, port))                # This server to a port

s.listen(4)                         # Now wait for client connection

print("Server now awaiting client connection on port %s" % (port))

#WINDOWS ONLY ACCEPTS SOCKETS FOR SELECT(), no standard in
input = [s, sys.stdin]


running = 1

while running:


    print("im right before the select")
    # when there's something in input, then we move forward
    # ignore what's in output and except because there's nothing
    # when it comes to sockets
    inputready, outputready, exceptready = select.select(input, [], [])

    print("i'm here na")
    # check who made a response
    for x in inputready:

        if x == s:
            print(s)
            #handle the server socket
            client, address = s.accept()
            print("connection comming in")
            input.append(client)

        elif x == sys.stdin:
            # handle standard input
            stuff = sys.stdin.readline()
            if stuff == "exit":
                running = 0
            else:
                print("you typed %s" % (stuff))


        else:
            #handle all other sockets
            data = x.recv(1024)
            print("i received " + data)
            if data:
                if data == "exit":
                    x.close()
                    input.remove(x)
                    running = 0
                else:
                    x.send(data)
                    print("I am sending %s" % (data))
            else:
                x.close()
                input.remove(x)


s.close()

任何帮助或想法将不胜感激。 谢谢!!

好吧,我知道你 7 年前问过这个问题,但我有类似的问题,所以我想我会回答你。 我仍在工作并修复具有相同功能的程序,但我知道的一件事是作为select.select()参数的列表需要是文件描述符 (int)。

所以如果你有这个块

input = [s, sys.stdin]


running = 1

while running:


    print("im right before the select")
    # when there's something in input, then we move forward
    # ignore what's in output and except because there's nothing
    # when it comes to sockets
    inputready, outputready, exceptready = select.select(input, [], [])

我要说的第一件事是将您的阅读列表更改为 not be input 您可能会与 input() 函数发生一些冲突,这可能会导致令人困惑的错误。 之后,您希望这些值成为文件描述符。 所以第一行应该是

inputSockets = [s.fileno(), sys.stdin.fileno()]

然后在检查哪个套接字准备就绪时,您会想要这样做

for x in inputready:
    if x == s.fileno():
        # Read from your s socket
    elif x == sys.stdin().fileno():
        # Read from stdin
    else:
        '''
        Here you would want to read from any other sockets you have.
        The only problem is your inputSockets array has ints, not socket
        objects. What I did was store an array of actual socket objects
        alongside the array of file descriptors. Then I looped through the
        list of sockets and found which socket's .fileno() matched x. You could
        probably be clever and use a dict() with the filenos as key and socket as
        value
        '''

我刚刚在编写 unix 域套接字 (UDS) 接口时遇到了这个问题。 服务器套接字 ID 用于接受传入的客户端连接。 这几乎就是它所做的一切。 一旦客户端被接受,读取使用它自己的文件描述符。 这样的事情有效:

conn = None
inputReady, Null, Null = select.select(inputSockets, [], [])
for x in inputReady:
   if x == s.fileno():
     # accept incoming connect and add to poll list
     conn, addr = s.accept()
     inputReady.append(conn.fileno())
   elif x = sys.stdin.fileno():
      # read whole line and remove newline
      cmd = sys.stdin.readline()[:-1]
      ...
   elif conn and x == conn.fileno():
      data = conn.recv(msglen)
      if data:
          ....
      else:
          # connection has ended, remove from poll list and close
          if conn.fileno() in inputReady:
             inputReady.remove(conn.fileno())
          conn.close()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM