So i'm setting up a VoIP software and my connection thread to another peer has a UDP socket (to send audio) and a tcp socket for signaling/text. Now, to bypass firewalls and NAT, i need to use a TCP Hole punching technique, meaning i need to try and connect from this side of the call, which will open up holes in the firewall and NAT, and then i await a connection on the same port and the other peer should be able to connect to me.
try {
// UDP Socket
DatagramSocket callSocket = new DatagramSocket(null);
callSocket.setReuseAddress(true);
callSocket.bind(new InetSocketAddress(myIP, 0));
//Send/receive a few packets on callSocket
// Addresses to use
InetSocketAddress myAddress = new InetSocketAddress(myIP, callSocket.getLocalPort());
InetSocketAddress targetAddress = new InetSocketAddress(InetAddress.getByName("192.168.1.1"), 6800);
// TCP Hole Punch
Socket tcpSocket = new Socket();
tcpSocket.setReuseAddress(true);
tcpSocket.bind(myAddress);
try {
tcpSocket.connect(targetAddress, 50);
// this never connects. it's just meant to open a hole in a firewall
} catch (SocketTimeoutException ignore) {
System.out.println("Timeout!");
}
tcpSocket.close();
// Open up TCP socket
ServerSocket tcpTempSocket = new ServerSocket();
tcpTempSocket.setReuseAddress(true);
tcpTempSocket.bind(myAddress);
// accept connection and do stuff
} catch (Exception ex) {
ex.printStackTrace();
}
When i get to the 3rd and final bind, i get the "Bind Exception: Address already in use". I googled it up and read that the previous socket could still be hanging on something and wasn't closing, etc.
EDIT: this only happens in some computers. On others, it binds everything without an issue
EDIT: using "netstat", i can see that the connection is being hung up on "SYN_SENT" state on the computer where the bind goes wrong
Anyone have any tips on why this happens or how to i go around it?
close
is not sufficient. You need toshutdown
the sending side, then continue trying to receive until you get a normal close, and then you can callclose
on your side. – David Schwartzpid
. – Princeclose
without attempting a graceful shutdown, the TCP stack attempts to terminate the connection attempt. Until it finishes, you cannotbind
to the same address again -- think about it -- what would happen if it allowed thebind
and you attempt to make an outbound connection to the same IP and port? How would it know which connection attempt packets it received referred to? You are forcing the very condition you don't want. – David Schwartz