2015-03-18 151 views
0

我有一个GPS调制解调器(Sixnet BT-5800),它试图通过以太网向我的Linux客户端定时发送GPS NMEA消息。Python Socket编程 - 消息被截断

在客户端我有一个python脚本正在运行。我希望如果有人能够确定我在这里做错了什么。

''' 
The main program waits on the TCP socket to receive data, parses the data into 
GPS NMEA sentences and writes them to the MySQL database 
''' 
# python library 
import configparser 
import select 
import socket 
import sys 
from time import sleep 

# custom library 
#import gpsnmeapacketparser 

# open the configuration files 
config = configparser.ConfigParser() 
files = ['.config.host', '.config', '.config.mysql'] 
dataset = config.read(files) 
if (len(files) != len(dataset)): 
    print("Error: Failed to open/find configuration files. Has this package been installed?") 
    exit() 


def main(): 
    host_address = config['HOST']['IPAddress'] 
    host_gps_port = config['HOST']['GPSPort'] 

    # create a tcp/ip socket 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

    server_address = (host_address, int(host_gps_port, 10)) 

    print("Binding socket:", server_address) 
    sock.bind(server_address) 

    # listen for incoming connections 
    sock.listen(5) 


    while True: 
     block = "" 

     # wait for a connection 
     print('waiting for a connection') 
     connection, client_address = sock.accept() 

     print('connection from', client_address) 

     data = bytearray([]) 
     buf = bytearray([]) 

     while True: 
      buf = connection.recv(10) 

      if buf != b'': 
       data += buf 
      else: 
       break 

     if data != b'': 
      block = data.decode("utf-8") 
      print(block) 
      print() 

     else: 
      connection.close() 

if __name__ == "__main__": 
    sys.exit(main()) 

调制解调器似乎在512字节的消息最大。运行Python脚本,我会看到输出类似如下:

waiting for a connection 
connection from ('192.168.0.1', 4433) 
waiting for a connection 
connection from ('192.168.0.1', 4434) 
$GPRMC,210458.00,A,4437.35460,N,07545.93616,W,000.0,000.0,180315,13.4,W,A*0F 
$GPGGA,210458.00,4437.35460,N,07545.93616,W,1,08,0.91,00121,M,-034,M,,*54 
$GPGLL,4437.35460,N,07545.93616,W,210458.00,A,A*79 
$GPVTG,000.0,T,013.4,M,000.0,N,000.0,K,A*25 
$GPGSV,3,1,09,31,32,089,36,03,19,236,29,16,77,229,36,23,57,292,35*75 
$GPGSV,3,2,09,10,07,326,23,29,08,032,17,08,58,067,41,09,29,312,36*73 
$GPGSV,3,3,09,27,26,164,37,,,,,,,,,,,,*46 
$GPGSA,A,3,31,03,16,23,10,29,09,27,,,,,1.61,0.91,1.33*0C 
$GPZDA,210458.00,18,0 

waiting for a connection 
connection from ('192.168.0.1', 4435) 
waiting for a connection 
connection from ('192.168.0.1', 4436) 
$GPRMC,210528.00,A,4437.35458,N,07545.93617,W,000.0,000.0,180315,13.4,W,A*03 
$GPGGA,210528.00,4437.35458,N,07545.93617,W,1,07,1.05,00121,M,-034,M,,*5B 
$GPGLL,4437.35458,N,07545.93617,W,210528.00,A,A*75 
$GPVTG,000.0,T,013.4,M,000.0,N,000.0,K,A*25 
$GPGSV,3,1,09,31,32,089,36,03,19,236,30,16,77,229,36,23,57,292,35*7D 
$GPGSV,3,2,09,10,07,326,22,29,08,032,06,08,58,067,42,09,29,312,35*72 
$GPGSV,3,3,09,27,26,164,35,,,,,,,,,,,,*44 
$GPGSA,A,3,31,03,16,23,10,09,27,,,,,,1.77,1.05,1.42*0A 
$GPZDA,210528.00,18,03, 

waiting for a connection 
connection from ('192.168.0.1', 4437) 

在执行过程connection.recv(10)运行,以收集数据,直到它返回一个空数组,然后它运行一次和超时。 (这是一个次要问题,我怎么能保证我收到的所有数据,而不必等待超时?

这里是一个tcpdump的

17:09:27.907495 IP 192.168.0.1.4621 > 192.168.0.5.8763: Flags [F.], seq 1, ack 1, win 2920, options [nop,nop,TS val 5166242 ecr 6220255], length 0 
17:09:27.907667 IP 192.168.0.5.8763 > 192.168.0.1.4621: Flags [F.], seq 1, ack 2, win 202, options [nop,nop,TS val 6224000 ecr 5166242], length 0 
17:09:27.908091 IP 192.168.0.1.4621 > 192.168.0.5.8763: Flags [.], ack 2, win 2920, options [nop,nop,TS val 5166242 ecr 6224000], length 0 
17:09:27.910329 IP 192.168.0.1.4622 > 192.168.0.5.8763: Flags [S], seq 2455146170, win 5840, options [mss 1460,sackOK,TS val 5166244 ecr 0,nop,wscale 1], length 0 
17:09:27.910390 IP 192.168.0.5.8763 > 192.168.0.1.4622: Flags [S.], seq 3558179681, ack 2455146171, win 25760, options [mss 1300,sackOK,TS val 6224000 ecr 5166244,nop,wscale 7], length 0 
17:09:27.910796 IP 192.168.0.1.4622 > 192.168.0.5.8763: Flags [.], ack 1, win 2920, options [nop,nop,TS val 5166245 ecr 6224000], length 0 
17:09:27.914219 IP 192.168.0.1.4622 > 192.168.0.5.8763: Flags [P.], seq 1:513, ack 1, win 2920, options [nop,nop,TS val 5166248 ecr 6224000], length 512 
17:09:27.914309 IP 192.168.0.5.8763 > 192.168.0.1.4622: Flags [.], ack 513, win 210, options [nop,nop,TS val 6224001 ecr 5166248], length 0 
17:09:42.895197 IP 192.168.0.1.4622 > 192.168.0.5.8763: Flags [F.], seq 513, ack 1, win 2920, options [nop,nop,TS val 5181229 ecr 6224001], length 0 
17:09:42.897588 IP 192.168.0.1.4623 > 192.168.0.5.8763: Flags [S], seq 2470830214, win 5840, options [mss 1460,sackOK,TS val 5181231 ecr 0,nop,wscale 1], length 0 
17:09:42.897643 IP 192.168.0.5.8763 > 192.168.0.1.4623: Flags [S.], seq 2665688556, ack 2470830215, win 25760, options [mss 1300,sackOK,TS val 6227747 ecr 5181231,nop,wscale 7], length 0 
17:09:42.898114 IP 192.168.0.1.4623 > 192.168.0.5.8763: Flags [.], ack 1, win 2920, options [nop,nop,TS val 5181232 ecr 6227747], length 0 
17:09:42.898383 IP 192.168.0.5.8763 > 192.168.0.1.4622: Flags [F.], seq 1, ack 514, win 210, options [nop,nop,TS val 6227747 ecr 5181229], length 0 
17:09:42.898773 IP 192.168.0.1.4622 > 192.168.0.5.8763: Flags [.], ack 2, win 2920, options [nop,nop,TS val 5181232 ecr 6227747], length 0 

它看起来的输出虽然调制解调器从来没有得到正确的信号发送剩余的字符,那些巨大的序列号可能是错误代码?

我不明白,如果错误是在我的代码,或者如果调制解调器使用一些非标准的TCP?

回答

1

TCP是一个流媒体协议,您没有收到基于消息数据包。大幅增加缓冲区大小,并准备好接收可能被破坏并分散在多个接收操作中的消息。

所以,这是一个TCP问题,但这是正常的。因为正如我所说TCP是一个流媒体协议。

如果客户端发送者做到这一点没有任何停顿:

  • 发送10字节
  • 发送10个字节

接收器很可能会得到这样的结果:

  • 接收20个字节

现在,如果接收者的缓冲区太小,他很可能会丢失部分信息。当然不是你想要的。 接收器接收数据的方式是不可预测的,你不应该依赖它。从理论上讲,您应该准备好每字节接收消息字节。但是,由于TCP是以最智能的方式使用MTU,所以不太可能每字节接收字节。但事情是你只是不知道哪些消息将通过不同的接收呼叫传播。

底线让您的接收缓冲区的大小为几k。

+0

不幸的是,它看起来并不那么简单。即使将缓冲区设置为4096(最大消息为〜535),我也看到了相同的结果。调制解调器发送512字节,我们确认,调制解调器发送长度为0的序列号513。 – user3817250 2015-03-19 14:29:12

+0

当您在套接字上接收到0个字节时,这意味着服务器已关闭了套接字的末尾,并且不再发送。问题是为什么? – 2015-03-19 14:53:43

+0

现在看起来越来越像是调制解调器方面的问题,这正是我希望在此线程中确定的问题。谢谢你的帮助。 – user3817250 2015-03-19 17:21:42