2013-08-05 26 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