Question

I want to recieve data from my gps-tracker. It sends data by tcp, so I use xinetd to listen some tcp port and python script to handle data. This is 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
} 

Config in /etc/services

gps-gprs        57003/tcp           # Tracking system

And Python script gps.py

#!/usr/bin/python
import sys

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

if __name__ =='__main__':
    main()

The tracker sends data strings in raw text like

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

The problem is that sys.stdin in python script doesn't recieve end of line or end of file character and sys.stdin.readline() goes forever. I tried to send data from another pc with a python script

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

and if the message is 'hello', it fails, but if the message is 'hello\n', it's ok and everything is fine. But I don't know ho to tell tracker or xinetd to add this '\n' at the end of messages. How can I read the data from sys.stdin without EOF or EOL in it?

Was it helpful?

Solution

sys.stdin.readline() waits forever until it receives a newline. Then it considers the current line to be complete and returns it in full. If you want to read data that doesn't contain newlines or you don't want to wait until a newline is received before you process (some of) the data, then you're going to have to use something other than readline. Most likely you should call read, which reads arbitrary data up to a given size.

However, your GPS appears to be sending data in the well-known NEMA format, and that format certainly terminates each line with a newline. Actually, it probably terminates each line with CRLF (\r\n) but it is possible that the \r could be getting munged somewhere before it gets to your TCP socket. Either way there's a \n at the very end of each line.

If your readline call is hanging without returning any lines, most likely it's because the sender is buffering lines until it has a full buffer. If you waited long enough for the sender's buffer to fill up, you'd get a whole bunch of lines at once. If that's what's happening, you'll have to change the sender to that it flushes its send buffer after each NEMA sentence.

OTHER TIPS

Simple:

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

for i in data:
        print i

No newlines

It seems you are receiving # instead of <CR><LF>, just read until the # sign.

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

#do something with data
print 'ok'

My solution :

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

It :

  • find the newline in the entry,
  • replace it from the entry by '' (none) ~remove,
  • assigne it to variable.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top