2015-06-22 41 views
1

我在写一些必须单独绑定到IPv6和IPv4(UDP4,UDP6)的软件。我有一个现有的代码库,可以在其他地方工作,并且无法修改此任务。它的所有荣耀都会自动创建一个既可处理IPv6又可处理IPv4的套接字,因此,当我现有的不可修改代码尝试创建第二套套接字时,由于该端口已被使用,所以它会出错。如何在Java中单独绑定到IPv6和IPv4

相关:http://docs.oracle.com/javase/7/docs/technotes/guides/net/ipv6_guide/

我可以提供我的代码,但不认为这会回答这个问题有所帮助。非常感谢!

我的绑定功能(不是最终的生产代码):

private void bind(String uuid, String exclusiveStr, String portStr, CallbackContext c){ 

    final JSSocket socket = socketMap.get(uuid); 
    boolean exclusive = Boolean.parseBoolean(exclusiveStr); 
    int port=0; 
    try{ 
     port=Integer.parseInt(portStr); 
    }catch(Exception e){ 
     //port wasn't there, use default value 
    } 
    Log.d("bind", "Attempting to bind uuid: " + uuid + " to port: " + port); 
    socket.bind(exclusive, port); 
    Log.d("bind", "new port: " + socket.getPort()); 
    final InetAddress inetAddress = socket.getAddress(); 

    //HashMap<String, String> setAddress= new HashMap<String,String>(); 
    //setAddress.put("address", socket.getAddress().getHostAddress()); 
    //setAddress.put("port", "" + socket.getPort()); 
    JSONObject json = new JSONObject(); 
    PluginResult result; 
    try { 
     json.put("address", socket.getAddress().getHostAddress()); 
     json.put("port", "" + socket.getPort()); 
     Log.d("BINDING********", json.toString()); 
     c.success(json.toString()); 
    }catch(JSONException e){ 
     //todo better 
     e.printStackTrace(); 
    } 
} 

其他代码使用的Node.js的数据报模块。我必须写入该界面。它有单独的(我的理解)用于IPv4和IPv6的套接字。

+0

为什么现有的代码库在这里工作,当它在别处工作? –

+0

请参阅上面的代码和原因 –

回答

-1

有两种选择:在bind()的第二次调用周围尝试{} catch(),并允许它无害地失败。或者你可以bind()一次,然后尝试在IPv4和IPv6上发送数据包,如果两者都失败,则bind()另一个。

你的代码在其他地方工作的原因是一些内核提供了一个适用于两者的套接字,而其他的则不然。

0

在操作系统级别,这由IPV6_V6ONLY标志控制。不幸的是,java似乎没有提供任何访问权限。

一种可能的解决方法可能是绑定到单个IP地址。 Afaict绑定到单独的IP地址将始终将您的套接字限制为一个IP版本。