【问题标题】:select and Pipes trouble in PythonPython中的选择和管道问题
【发布时间】:2013-09-13 12:18:12
【问题描述】:

作为上一篇文章的扩展,不幸的是,它似乎已经死了: select.select issue for sockets and pipes。自从这篇文章以来,我一直在尝试各种无济于事的事情,我想看看是否有人知道我哪里出错了。我正在使用 select() 模块来识别管道或套接字上何时存在数据。套接字似乎工作正常,但事实证明管道存在问题。

我已按如下方式设置管道:

pipe_name = 'testpipe'
if not os.path.exists(pipe_name):
    os.mkfifo(pipe_name)

管道读取为:

pipein = open(pipe_name, 'r')
line = pipein.readline()[:-1]
pipein.close()

它作为一个独立的代码可以完美地工作,但是当我尝试将它链接到 select.select 函数时它失败了:

inputdata,outputdata,exceptions = select.select([tcpCliSock,xxxx],[],[])

我尝试在 inputdata 参数中输入“pipe_name”、“testpipe”和“pipein”,但总是收到“未定义”错误。查看其他各种帖子,我认为这可能是因为管道没有对象标识符,所以我尝试了:

pipein = os.open(pipe_name, 'r')
fo = pipein.fileno()

并将“fo”放入 select.select 参数中,但得到 TypeError: an integer is required。在使用“fo”的这种配置时,我也遇到了错误 9:错误的文件描述符。任何我做错的想法都将不胜感激。

编辑代码: 我设法找到了解决它的方法,尽管不确定它是否特别整洁-我会对任何 cmets 感兴趣- 修改后的管道设置:

pipe_name = 'testpipe'
pipein = os.open(pipe_name, os.O_RDONLY)
if not os.path.exists(pipe_name):
    os.mkfifo(pipe_name)

管道读取:

def readPipe()
    line = os.read(pipein, 1094)
    if not line:
        return
    else:
        print line

监控事件的主循环:

inputdata, outputdata,exceptions = select.select([tcpCliSock,pipein],[],[])
if tcpCliSock in inputdata:
    readTCP()   #function and declarations not shown
if pipein in inputdata:
    readPipe()

一切都很好,我现在唯一的问题是在 select 的任何事件监视开始之前从套接字读取代码。一旦与 TCP 服务器建立连接,就会通过套接字发送命令,我似乎必须等到第一次读取管道后才能通过此命令。

【问题讨论】:

  • 你在windows盒子上? Select 仅适用于那里的套接字。
  • 在您最初的问题中,您写道“管道当前保存来自 html 表单的传入数据,套接字构成与服务器的连接,该服务器以不同的时间间隔发送 TCP/IP 命令。表单和服务器是在同一个局域网但不同的计算机上。”命名管道 (fifos) 是单台机器本地的,不能从另一台机器访问。您已经显示了正在读取的 fifo,但没有显示 fifo 写入器。您的问题缺少某些内容。
  • 嘿斯宾塞,不是 Windows,已经设法让它工作了。
  • 嘿msw,是的,我认为我的描述不是很好。该表单与创建 fifo 的服务器位于同一台机器上(该表单通过其在 LAN 上的 IP 地址访问)。表单中的数据被放到管道上,python 代码通过 select 函数从中读取数据。 TCP 命令来自另一台机器,该机器本身就是服务器,因此我的机器充当客户端。我已经更改了我的 os.open 命令以包含 write 虽然我没有使用它。 pipein = os.open(pipe_name, os.O_WRONLY)。现在 select 命令会获取来自套接字和管道的数据。

标签: python sockets select pipe


【解决方案1】:

根据docs,select 需要来自os.open 或类似的文件描述符。因此,您应该使用select.select([pipein], [], []) 作为您的命令。

或者,如果您使用的是 linux 系统,则可以使用 epoll

poller = epoll.fromfd(pipein)
events = poller.poll()
for fileno, event in events:
  if event is select.EPOLLIN:
    print "We can read from", fileno

【讨论】:

  • 嗨 Spencer,感谢您的评论,在我看到它之前,我设法找到了一种方法来做到这一点,尽管它与您推荐的略有不同。我已经很好地了解了如何使用 epoll,这可能是我最终会采用的方式,因为它看起来很整洁。如果您有兴趣,我已经在我的原始帖子中添加了一个编辑,描述了我所做的事情,我会对您的 cmets 感兴趣。再次感谢
猜你喜欢
  • 2015-10-24
  • 2019-01-30
  • 1970-01-01
  • 2020-09-20
  • 2018-06-12
  • 2013-07-18
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多