2014-02-09 108 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