我使用基于BaseServer的UDPServer接收frag UDP数据包。
但有些数据包大于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 :(得分: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
我的修改后的main(请参阅server.max_packet_size)
if __name__ == '__main__':
server = SocketServer.UDPServer((HOST, LISTEN_PORT), MyUDPHandler)
server.max_packet_size = 8192*2
server.serve_forever()
答案 1 :(得分:0)
这里涉及许多因素。
首先,UDP的最大有效载荷大小为65535.但是,IPv4报头和UDP报头计数为65535的一部分,因此实际上,最大用户有效载荷大小为65504。
其次,您不能在堆栈中的任何级别接收超过最小的接收缓冲区。我可以解释如何绕过这个,但我不会,因为......
最后,任何大于单个MTU的数据包都会在此过程中出现碎片。除非碎片恰好按照它们发送的完全相同的顺序到达,并且没有任何相当大的延迟,否则它们不能被重新组装,因此您将丢失整个数据包。即使在仅有1%以太网数据包丢失的连接上,您也可能会丢失超过三分之一的大型UDP数据包。很少有申请可以接受。
那么,你应该怎么做?那么,有三个不同的答案:
在某些情况下,选项2是有意义的 - 例如,对于许多流式A / V协议,音频帧,视频iframe和元数据都低于1K,并且通常可以丢弃而没有重大后果,所以它不是值得使用TCP来处理关键帧的成本,因此他们将关键帧分解为1K块(例如,窗口的矩形部分)或者仅为关键帧等编写显式TCP特征检查和重发代码。
但通常情况下,如果你需要发送大量的消息,TCP会更容易。