在没有换行符或EOF的情况下从sys.stdin读取



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

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读取数据?

简单:

data=sys.stdin.read().splitlines()
for i in data:
        print i

无换行

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

然而,你的GPS似乎是以众所周知的NEMA格式发送数据,这种格式肯定会用换行符终止每一行。事实上,它可能会用CRLF(rn)终止每一行,但r可能在到达TCP套接字之前就被阻塞了。无论哪种方式,在每行的最后都有一个n

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

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

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

我的解决方案:

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

它:

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