2014-02-09 110 views
0

基本本地错误发送

我有一个是在发送多个线程使用DatagramChannel.send包的应用程序的每个到它自己的IP地址/端口和每个人的保持恒定比特率/带宽。时不时地,我得到这个错误:

java.net.SocketException: Invalid argument: no further information 
    at sun.nio.ch.DatagramChannelImpl.send0(Native Method) 
    at sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(Unknown Source) 
    at sun.nio.ch.DatagramChannelImpl.send(Unknown Source) 
    at sun.nio.ch.DatagramChannelImpl.send(Unknown Source) 
    ... 

它发生在随机的 - 有时5分钟,一天后,有时启动之后 - 所以我真的有问题重现它进行测试。而在我的家用机器上,我根本无法复制它。

环境

  • 的Windows 7,第8和Server 2012中(全部64位)
  • 64位的Java 7更新45

更多信息

的应用正在发送SI/EIT数据到DVB-C网络。我为每个80-120个线程创建一个188字节的数组列表并给它使用。线程获取列表并循环遍历列表,直到提供新列表。

  • 该错误通常发生在多个通道上。但它也可能发生在一个人身上。
  • 直到我们有40多个线程时,才会发生错误。
  • 循环遍历列表时发生错误,而不是当我将新列表绑定到线程时。
  • 该应用程序没有用完内存。它通常运行高达JVM内存的70%。
  • 奇怪的部分:如果我运行多个应用程序的每个实例〜10个线程的问题是相同的。

简化代码示例

for(int i = 0; i < 100; ++i) { 
    final int id = i; 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
     final Random r = new Random(); 
     final List<byte[]> buffer = Lists.newArrayList(); 
     for(int i = 0; i < 200; ++i) { 
      final byte[] temp = new byte[188]; 
      r.nextBytes(temp); 
      buffer.add(temp); 
     } 

     final SocketAddress target = new InetSocketAddress("230.0.0.18", 1000 + id); 
     try (final DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET)) {        
      channel.configureBlocking(false); 
      channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, NetworkInterface.getByName("eth0"));    
      channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, 8); 
      channel.setOption(StandardSocketOptions.SO_REUSEADDR, true); 
      channel.setOption(StandardSocketOptions.SO_SNDBUF, 1024 * 64); 

      int counter = 0; 
      int index = 0; 
      while(true) { 
      final byte[] item = buffer.get(index); 
      channel.send(ByteBuffer.wrap(item), target); 
      index = (index + 1) % buffer.size(); 
      counter++; 
      Thread.sleep(1); 
      }    
     } 
     catch(Exception e) { 
      LOG.error("Fail at " + id, e); 
     } 
     } 
    }).start(); 
} 

编辑:

1)@EJP:我设置设置多播特性,我使用的实际应用正在做联接(并阅读一些数据)。但即使我将它们删除后问题仍然存在。

2)如果我只需要发送UDP数据包,我应该使用其他的API吗?我可以找到的所有示例都使用DatagramChannel(或更早的替代方法)。

3)我仍然坚持这一点。如果任何人有一个想法,我甚至可以尝试,请让我知道。

+0

为什么你在没有进行任何连接时设置多播属性? – EJP

+0

你可以试试MulticastSocket。你不应该像这样使用非阻塞模式。在OP_WRITE上选择,而不是睡觉。 – EJP

回答

1

我有完全一样的问题,它是由目标InetSocketAddress中的零端口引起的,当调用发送方法时。

在你的代码中,目标端口被定义为1000 + i,所以它似乎不是问题。无论如何,我会记录抛出异常时使用的目标参数,以防万一。

+0

我没有找到答案。解决办法是更换服务器硬件,因此我怀疑是某种硬件故障或某些系统/网络级别问题。 – Ashes