0

I'm a little stumped and probably because I don't know how to search for this properly (I've tried many different keywords). Anyway, I'm attempting a variation of TCP hole punching(with a rendezvous server). I have created a TCP socket to the server and closed it without throwing any exceptions. But when I attempt to create a ServerSocket on the localport of the original socket it fails with IOException.

private static int LOCALPORT = 0;
private static String TARGETIP = "88.888.88.888";
private static int TARGETPORT = 8888;
try{
    InetAddress serverAddr = InetAddress.getByName(TARGETIP);
    socket = new Socket(serverAddr, TARGETPORT);
    LOCALPORT = socket.getLocalPort();
    socket.close();
    ServerSocket sSocket = new ServerSocket(LOCALPORT);
    Socket skt = sSocket.accept();
}
catch (IOException e){
}

I just cannot wrap my head around why I cannot close the socket and open a serversocket on the same port.

UPDATE: from logcat

java.net.BindException: bind failed: EADDRINUSE (Address already in use)
Caused by: libcore.io.ErrnoException: bind failed: EADDRINUSE (Address already in use)
RoboLam
  • 488
  • 6
  • 14
  • Fails with what IOException? – user207421 Jul 01 '14 at 05:27
  • Please tell me how to find out what IOException is given, and i'll be happy to supply it here. I'm not a very experienced programmer. I just know that the catch above executes and thus it's an IOException. – RoboLam Jul 01 '14 at 07:28
  • In the catch block add a log line whicht prints `e.getMessage()`. Also add a line `e.printStackTrace();` And then look in the logcat and post here. – greenapps Jul 01 '14 at 09:51

3 Answers3

0

I think your socket = new Socket(serverAddr, TARGETPORT); throws the IOException. Because the IP Address you are using is invalid. Otherwise this code should work fine.

nautilus
  • 1
  • 1
  • Thank you for your answer, however there is no issue creating the socket. My issue is with the ServerSocket creation. I put a dummy IP in there so I wouldn't have my actual public IP listed on here :) – RoboLam Jul 01 '14 at 06:05
  • @user2981258 Unless you answer my question above your question is liable to closure due to insufficient information. – user207421 Jul 01 '14 at 06:51
  • @EJP No need to be rude, I was trying to figure out how to answer your question(to no avail) but could answer this one immediately. – RoboLam Jul 01 '14 at 07:29
0

You will get an IOException trying to listen on the just retrieved local port:

 bind failed: EADDRINUSE (Address already in use)

That should be in my opinion:

 port already in use

Why that port is not released i don't know. Would there be a possibility to unbind it?

greenapps
  • 11,154
  • 2
  • 16
  • 19
-1

I believe I have solved my own problem thanks to greenapps and some additional searching online. Instead of closing the original socket, you need to set it to reuse instead! So simple, wow.

private static int LOCALPORT = 0;
private static String TARGETIP = "88.888.88.888";
private static int TARGETPORT = 8888;
try{
    InetAddress serverAddr = InetAddress.getByName(TARGETIP);
    socket = new Socket(serverAddr, TARGETPORT);
    LOCALPORT = socket.getLocalPort();
    //socket.close();
    socket.setReuseAddress(true);
    ServerSocket sSocket = new ServerSocket(LOCALPORT);
    Socket skt = sSocket.accept();
    sSocket.close();
}
catch (IOException e){
    e.getMessage();
    e.printStackTrace();
}
RoboLam
  • 488
  • 6
  • 14
  • No. That doesn't solve anything. 'socket' is already bound when you call setReuseAddress(), which therefore does nothing. – user207421 Jul 01 '14 at 20:57
  • Hey buddy, did you try to run the code? If you did, you'll see that it no longer throws an exception and I can create the ServerSocket. Please see the link where YOU also posted on (albeit you did not provide anything helpful there either) which contained the answer: [oracle forum](https://community.oracle.com/thread/1149986?start=0&tstart=0). Thanks for downvoting without knowing what you're talking about! – RoboLam Jul 01 '14 at 21:41