【问题标题】:Windows select() only receives, doesn't sendWindows select() 只接收,不发送
【发布时间】:2015-08-08 15:04:41
【问题描述】:

我让我的 Windows 计算机连接到我的 linux python 服务器。

该服务器非常适合 linux 用户,但我希望它也可以在 Windows 上运行。我做了一些研究,发现 Windows 上的 select.select() 函数可以在没有 stdin 管道的情况下工作,但是当我这样做时,它不会向服务器发送任何数据,只会接收。

代码:

 __author__ = 'root'
import socket
import datetime
import getpass          # Get username
import sys
import threading
import thread
import select

def client():

   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
   address = "192.168.1.17"
   sock.bind((str("192.168.1.231"), int(2222)))
   sock.connect(("192.168.1.17", int(23657)))
   sock.setblocking(0)
   sock.send(getpass.getuser()+"[$ID$]zivofek")

   socket_list = [sys.stdin, sock]
   partner = raw_input("Chat partner: ")

   while 1:
       try:
           message = raw_input()
           sock.sendall(message)
           data = sock.recv(1024)
           print data
       except:
           continue

def get_time():
   return datetime.datetime.strftime(datetime.datetime.now(), '%H:%M:%S')

def main():
   client()

if __name__ == "__main__":
   main()

知道如何在 Windows 中同时接收和发送吗?

【问题讨论】:

  • select 本身不会发送任何内容。你的意思是你没有得到“写”事件?同样,发布出现问题的代码是最好的选择。
  • 实际上-我在 Windows 中没有客户端代码。我基本上想让客户端能够以任何方式接收和发送到服务器。在 python 中,它使用简单的选择——可写时写入,可读时读取。我正在寻找一种在 Windows 中实现它的方法,到目前为止,我一次只能做一个,而不是两个。
  • 试过pythonsocket.sendall()函数?
  • 老实说我没有,现在尝试-引发错误:无法立即完成非阻塞套接字操作。你介意举个例子吗?非常感谢您的帮助!
  • 您介意展示您的代码吗?我们这里不是免费的导师,你应该做你自己的工作:)

标签: python linux windows sockets


【解决方案1】:
socket_list = [sys.stdin, sock]

假设上述 socket_list 的目的是将其传递给 select() ...这是行不通的。 select() 的 Windows 实现只适用于套接字,而 sys.stdin 不是套接字。

这个问题没有简单的解决方法(*);也就是说,解决问题的一种方法是在一个单独的线程中从 sys.stdin 读取,并让该线程将数据发送()到连接的套接字对的一端,并将该对的另一端放入您传递给 select() 的列表。或者,您可以在 select() 中设置一个超时,以便 select() 经常返回,让您的偶数循环 check 以查看 stdin 上是否有任何可用字节(尽管这种机制要么 CPU 效率低下,要么高延迟,取决于您传递给 select() 的超时值——这是否可以接受取决于您的特定使用场景)

(*) 好的,有一个简单的解决方法:不要费心尝试在 Windows 中运行程序... ;)

【讨论】:

    【解决方案2】:

    除非您真的想多路复用来自不同来源的事件(即不使用 select() 时),否则不要将套接字设置为非阻塞。

    这里只是正常阻止sendall() 就可以了。还要检查 recv() 的返回长度 - 它在 some 数据可用时返回,接收零字节意味着另一端关闭了连接。

    同样,不要在客户端 TCP 套接字上设置 bind() 或设置 SO_REUSEADDR

    【讨论】:

      猜你喜欢
      • 2011-03-09
      • 2019-07-10
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 2014-09-30
      • 2017-09-04
      相关资源
      最近更新 更多