I'm writing some software that has to bind to IPv6 and IPv4 (UDP4, UDP6) individually. I have an existing code base that works elsewhere and can't be modified for this task.
Java, in all of its glory, automatically creates a socket that can handle both IPv6 and IPv4, so when my existing unmodifiable code tries creating the second set of sockets, it errors out because the port is already in use.
Relevant: http://docs.oracle.com/javase/7/docs/technotes/guides/net/ipv6_guide/
I can provide code that I have, but don't think it will help in answering this question. Thank you so much!
My bind function (not final production code):
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();
}
}
The other code uses Node.js's datagram module. I have to write to that interface. It has separate (my understanding) sockets for IPv4 and IPv6.
You have two options: Either try{}catch() around the second invocation of bind(), and allow it to fail harmlessly. Or you can bind() once, then try to send yourself a packet both on IPv4 and IPv6, and if either fails, bind() the other.
The reason your code worked elsewhere is that some kernels provide a socket that works on both, and others do not.