2015-03-18 152 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