0

I made a simple socket application using Java.Sockets. I ran client and the server at the same pc which is connected a modem with some other pcs. Client can connect to server with my local ip. But when it try to connect with external ip it fails.

Here the server code:

    int portno=Integer.parseInt(args[0]);
    ServerSocket ssock = new ServerSocket(portno);


    while(true){

        Socket csock = ssock.accept();

        PrintWriter out = new PrintWriter(csock.getOutputStream(), true);
        BufferedReader in = new BufferedReader( new InputStreamReader(csock.getInputStream()));

        String buffer = in.readLine();

        System.out.println(buffer);

        csock.close();

    }

And client code:

    public static void main(String args[]) throws Exception{
    String ip="My External IP";
    int port=Integer.parseInt(args[0]);
    Socket sock = new Socket(ip,port);
    PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
    BufferedReader in = new BufferedReader( new InputStreamReader(sock.getInputStream()) );
    BufferedReader stdin =  new BufferedReader( new InputStreamReader(System.in) );

    String buffer=stdin.readLine();

    out.println(buffer);

    sock.close();

}
  • 1
    Welcome to Stack Overflow, please take the [Tour](http://stackoverflow.com/tour). – DavidPostill Aug 23 '14 at 17:05
  • 1
    Check your firewall. – Kayaman Aug 23 '14 at 17:07
  • 1
    Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, **a specific problem or error** and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). – DavidPostill Aug 23 '14 at 17:07
  • 1
    What is the error message? What makes you believe that the client can access a server (on the same machine) via a public ip address? What happens if you try and run the client on a different machine that is outside of your network? – DavidPostill Aug 23 '14 at 17:10

1 Answers1

0

This is where Sockets get complicated. They work fine on a closed network, but once they get separated by a Network Address Translator (router) you need to look for other methods.

Routers block all incoming traffic/connections unless the router is specifically port-fowarded or the incoming traffic is an answer to it's own request (e.g getting a webpage)

In order to allow your router to accept the connection you need to configure it to do so. The alternative is to use a method called "hole-punching". This is a technique used by software like Skype. The technique varies, and is largely unofficial, but the general concept behind it is:

  • Computer A want's to access Computer B
  • Computer A and Computer B are unaware of each other's location, but both know of an official super node. The super node holds a list of all connected users.
  • Once Computer A and Computer B retrieves each others location from the super node.
  • Computer A sends request to computer B, creating a hole in it's router where it's awaiting a response.
  • Computer B doesn't get the request, it's own router blocks the request, but it knows Computer A wants to access it by talking to the super node.
  • Computer B sends a new packet of data back to Computer A through the hole in the router, making it think that it's received it's response. Computer B now has a hole, and the connection is reversed to make it 2 way. Both computers are now connected.

Hole-punching is one of the only ways to connect to clients together, although it does require a third "super node". Hole-punching is an unofficial solution, and unfortunately flawed. Not all routers support hole-punching, meaning there is no concrete way to connect clients. There is another option, using a STUN or ICE server. There is very little documentation online, but I understand that it works as a relay to connect of the two clients. I myself have posted a question about STUN servers and clients.

There is a long going fight between security and connectivity, and until it's been resolved and p2p connections are standardised you're going to have to look of new and inventive ways to make it work.

I hope this helped a bit.

UDP Hole-punching: http://en.wikipedia.org/wiki/UDP_hole_punching

STUN: http://en.wikipedia.org/wiki/STUN

Marcus Cemes
  • 692
  • 1
  • 8
  • 18
  • I glad to this problem about the router. Because i will use it in a computer that connected to web with 3g mobile broandband. I have made a similar application in c++ before this. It has worked good with external ips. I thinked this problem about Java. But i have tried the c++ code in a pc that connected web with 3g mobile broadband. So there will be no problem in this pc with Java. Thank you. – user3933899 Aug 24 '14 at 13:51
  • Glad I could help. I don't know whether 3G will work, as NAT's are everywhere. But it could be possible. If not, look into hole-punching with ICE. – Marcus Cemes Aug 24 '14 at 13:53
  • I have another question. When i run this code with a port number once , I can't use the same port until reboot pc. I know it is caused i close the server with ctrl+z. So is there any way to close the server socked before server shut down ? – user3933899 Aug 24 '14 at 13:58
  • Socket.close() will close the socket. – Marcus Cemes Aug 24 '14 at 17:39
  • Also, might I suggest using finalise(), or even better, a shutdown hook? Just before a java program quits the finialize method will get called upon. You can release all sockets there, but I've heard that the finalise method doesn't always work. After a bit of research I've discovered you can create shutdown hooks. http://stackoverflow.com/a/5824066/1401876 – Marcus Cemes Aug 24 '14 at 17:50
  • If this answer helped you, might I suggest ticking it as a valid answer? – Marcus Cemes Aug 25 '14 at 07:25