2010-08-03 75 views
4

我试图发送一个UDP数据报(包含协议缓冲区消息)sendBufferSize()并获得消息太长异常之后过长UDP套接字:信息设置

java.io.IOException: Message too long 
at java.net.PlainDatagramSocketImpl.send(Native Method) 
at java.net.DatagramSocket.send(DatagramSocket.java:625) 

我设置的发送缓冲区的大小,和从getBufferSize()检查返回值,并且它比该消息较大:

byte[] b = msg.toByteArray(); 
      System.out.println("Serialised message in " + b.length + " bytes (max length: " + network.getSendBufferSize() + ")"); 
      DatagramPacket p = new DatagramPacket(b, b.length, host, port); 
      network.send(p); 

输出:

VM version: 16.3-b01-279 
Runtime version: 1.6.0_20-b02-279-9M3165 
Vendor: Apple Inc.  
Serialised message in 69424 bytes (max length: 531075) 
Problem sending packet: java.io.IOException: Message too long 

我可以理解它是否拒绝设置一个大尺寸的缓冲区,但它似乎设置了我所要求的任何内容,然后不履行它。

这是在OSX上;我曾与1.6和1.5

+0

谢谢你所有的答案。我希望避免TCP设置的麻烦,但显然这是不可能的。可惜的是,Java并没有正确报告可能的缓冲区大小(也没有API文档)。 – 2010-08-05 10:44:23

+0

这里没有证据表明Java不'正确报告可能的缓冲区大小'。首先没有实际做到这一点的API。只有实际的发送缓冲区大小:*底层操作系统*可以自由修改所要求的缓冲区大小,向上或向下;这不是UDP有效负载大小的唯一限制。 – EJP 2011-07-06 22:37:18

+0

@EJP:getSendBufferSize的文档说“为此DatagramSocket获取SO_SNDBUF选项的值,即平台用于在此DatagramSocket上输出的缓冲区大小。”把这个解释为可以使用的实际大小似乎并不合理。我发现那里的“平台”非常模糊,并将其作为报告底层操作系统要做什么的报道来阅读。我假定setSendBufferSize并不总是给你所要求的大小,但getSendBufferSize会告诉你你实际上可能拥有了什么。虽然谢谢澄清! – 2011-08-30 21:29:54

回答

2

UDP数据报的尝试都不能大于64K

1

UDP有一个最高限额有点短的64K。你的信息超过了这个限制。

此外,你不应该使用UDP来处理这么大的消息。当UDP碎片化时,如果一个段丢失,它必须重新传输整个事情。使用TCP。

+2

UDP不会重传任何内容。 – EJP 2015-07-14 19:19:16

9

(a)IPv4中UDP数据报有效载荷的限制是65535-28 = 65507字节,实际限制是路径的MTU,如果幸运的话,它更像1460字节。

(b)当UDP是零散的,它失去数据报,如果一个片段丢失,这是因为没有重传。

使用TCP。

+0

我们如何确保每次发送> 65535字节的数据? – 2016-09-23 10:21:52

+0

@ guru_001你*不能*在任何*时间发送超过* 65507 *字节,*正如我已经说过的。*有时我想知道为什么我打扰。 – EJP 2017-04-25 22:21:10

+0

感谢提示@EJP – 2017-04-30 12:03:40