我正在编写一些必须单独绑定到IPv6和IPv4(UDP4,UDP6)的软件。我有一个在其他地方工作的现有代码库,无法为此任务进行修改。
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)
在操作系统级别,它由IPV6_V6ONLY标志控制。不幸的是,java似乎没有提供任何访问权限。
一种可能的解决方法可能是绑定到各个IP地址。对单个IP地址的绑定将始终将您的套接字限制为一个IP版本。
答案 1 :(得分:-1)
您有两个选择:在第二次调用bind()时尝试{} catch(),并允许它无害地失败。或者你可以绑定()一次,然后尝试在IPv4和IPv6上发送自己的数据包,如果其中一个失败,则绑定()另一个。
您的代码在其他地方工作的原因是某些内核提供了一个适用于这两者的套接字,而其他内核则没有。