【问题标题】:reading from sys.stdin without newline or EOF从没有换行符或 EOF 的 sys.stdin 读取
【发布时间】:2012-08-31 17:49:11
【问题描述】:

我想从我的 gps-tracker 接收数据。它通过 tcp 发送数据,所以我使用 xinetd 来监听一些 tcp 端口和 python 脚本来处理数据。这是 xinetd 配置:

service gps-gprs
{
    disable     = no
    flags       = REUSE
    socket_type = stream
    protocol    = tcp
    port    = 57003
    user        = root
    wait        = no
    server      = /path/to/gps.py
    server_args     = 3
} 

在 /etc/services 中配置

gps-gprs        57003/tcp           # Tracking system

还有 Python 脚本 gps.py

#!/usr/bin/python
import sys

def main():
    data = sys.stdin.readline().strip() 
    #do something with data
    print 'ok'

if __name__ =='__main__':
    main()

跟踪器以原始文本形式发送数据字符串,例如

$GPRMC,132017.000,A,8251.5039,N,01040.0065,E,0.00,,010111,0,,A*75+79161234567#

问题是 python 脚本中的 sys.stdin 没有收到行尾或文件结尾字符,并且 sys.stdin.readline() 永远存在。我尝试使用 python 脚本从另一台电脑发送数据

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('', 57003))
s.sendall( u'hello'  )
data = s.recv(4024)
s.close()
print 'Received', data

如果消息是'hello',它会失败,但如果消息是'hello\n',没关系,一切都很好。但我不知道如何告诉 tracker 或 xinetd 在消息末尾添加这个 '\n'。如何在没有 EOF 或 EOL 的情况下从 sys.stdin 读取数据?

【问题讨论】:

  • 为什么需要使用.readline().read() 不会吗?
  • 我猜你需要.read(),直到你遇到一个特定的信号,上面写着“break here”,这不一定是换行符,我猜最后可能是#,或者$ 开头。

标签: python tcp tcplistener xinetd


【解决方案1】:

简单:

data=sys.stdin.read().splitlines()

for i in data:
        print i

没有换行符

【讨论】:

    【解决方案2】:

    sys.stdin.readline() 一直等待,直到收到换行符。然后它认为当前行是完整的并完整地返回它。如果您想读取不包含换行符的数据,或者您不想等到收到换行符后再处理(部分)数据,那么您将不得不使用 readline 以外的其他内容.很可能您应该调用read,它会读取任意数据到给定大小。

    但是,您的 GPS 似乎正在以众所周知的 NEMA 格式发送数据,并且该格式肯定会以换行符结束每一行。实际上,它可能会以 CRLF (\r\n) 终止每一行,但 \r 可能会在到达您的 TCP 套接字之前在某处被破坏。无论哪种方式,每行末尾都有一个\n

    如果您的readline 调用挂起而没有返回任何行,很可能是因为发送方正在缓冲行,直到它有一个完整的缓冲区。如果您等待发件人缓冲区填满的时间足够长,您将一次收到一大堆行。如果发生这种情况,您必须将发送者更改为在每个 NEMA 语句之后刷新其发送缓冲区。

    【讨论】:

      【解决方案3】:

      您似乎收到的是# 而不是<CR><LF>,请阅读直到# 符号。

      data = ""
      while len(data) == 0 or data[-1] <> '#':
          data += sys.stdin.read(1)
      
      #do something with data
      print 'ok'
      

      【讨论】:

        【解决方案4】:

        我的解决方案:

        var = sys.stdin.readline().replace('\n', '')
        

        它:

        • 在条目中找到换行符,
        • 将其从条目中替换为 '' (none) ~remove,
        • 将其分配给变量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-22
          • 2023-03-03
          • 2018-05-10
          • 1970-01-01
          相关资源
          最近更新 更多