2013-08-05 25 views
2

我使用基於BaseServer的UDPServer接收碎片UDP數據包。python更改UDPServer中的最大限制recv緩衝區

但有些數據包大於8192字節(@handle方法,打印len(數據)),我無法正確使用它們。

我的原代碼:

class MyUDPHandler(SocketServer.BaseRequestHandler): 
    def handle(self): 
     global arr_len_recv  
     data = self.request[0].strip() 
     socket = self.request[1] 
     s_recv_paylaod_len = len(data) 
     print "s_paylaod",binascii.hexlify(data) 

if __name__ == '__main__':  
    server = SocketServer.UDPServer((HOST, LISTEN_PORT), MyUDPHandler) 
    tmp = threading.Thread(None, loop_send, None,(param,server) , {}) 
    tmp.daemon=True 
    tmp.start() 
    poll=0.1 
    server.serve_forever(poll) 

所以我RTFM BaseServer,UDPServer,TCPSERVER。

python SocketServer documentation

我SocketServer.TCPServer例

class MyTCPHandler(SocketServer.BaseRequestHandler): 

     def handle(self): 
      self.data = self.request.recv(1024).strip() 

找到,但self.request獲取沒有recv的方法

如果您有任何解決方案,以修復或改變最大限制的recv緩衝區。

+0

RFC 768對於IPv4,最大有效載荷大小爲65535 – user1778354

+0

什麼是「我無法正確地使用它們」是什麼意思? – abarnert

+0

它不起作用,如果有效負載大於8192(我懷疑是緩衝區限制)。我將無法在處理方法中具有完整的有效負載。 – user1778354

回答

2

最後,我發現它在baseserver python source code

480 class UDPServer(TCPServer): 
481 
482 """UDP server class.""" 
483 
484 allow_reuse_address = False 
485 
486 socket_type = socket.SOCK_DGRAM 
487 
488 max_packet_size = 8192 

我修改主(見服務器。MAX_PACKET_SIZE)

if __name__ == '__main__':  
    server = SocketServer.UDPServer((HOST, LISTEN_PORT), MyUDPHandler) 
    server.max_packet_size = 8192*2 
    server.serve_forever() 
0

這裏涉及到很多因素。

首先,UDP的最大有效載荷大小爲65535。然而,IPv4報頭和UDP報頭數爲65535的一部分,所以實際上來講,最大的用戶,有效載荷大小爲65504.

其次,你可以」 t比堆棧中任何級別的最小接收緩衝區都多。我可以解釋如何解決這個問題,但我不會這樣做,因爲...

最後,任何大於單個MTU的數據包都會被分割。除非這些碎片恰好按照它們發送的順序到達,並且沒有任何可觀的延遲,否則它們不能重新組裝,因此您將丟失整個數據包。即使在只有1%以太網數據包丟失的連接上,也可能會有超過三分之一的大型UDP數據包丟失。有很少的應用程序,這是可以接受的。

那麼,你應該怎麼做?那麼,有三個不同的答案:

  1. 建立一個專用的網絡,可以保證近乎完美的可靠性。
  2. 將自己的協議寫在UDP之上,並將大數據包分解爲MTU大小的數據包。
  3. 只需使用TCP而不是UDP。

有些情況下,選擇2是有道理的 - 例如,許多流A/V協議,音頻幀,視頻I幀和元數據都在1K,並且通常可以沒有大的後果下降,所以使用TCP只是爲了處理關鍵幀是不值得的,所以相反,他們將關鍵幀分成1K塊(例如,窗口的矩形部分),或者爲關鍵幀編寫顯式的TCP類型檢查和重新發送代碼等等。

但是通常情況下,如果你需要發送大量的消息,TCP將會變得更容易。

+0

我知道所有這些,但我fuzz專有協議在UDP上使用高達8倍的經典MTU – user1778354