Search code examples
javasocketsrouterobjectinputstream

Java Socket Handshake OK, But No Other Data. Router or Java (or myself) To Blame?


I'm trying to set up a server/client connection in Java. I've connected my PC directly to the DSL, and it works fine through Windows 10 firewall. I reconnect to my TP-Link Archer C9 router with Virtual Server set for port 4023 and 4024. I get a SocketTimeoutException on the Client Side.

And Wireshark gives me a bunch of TCP Retransmissions saying 'hello server' after the handshake from the Client, when I filter for port 4023:

Server code:

public class ServerTester {

    public static void main(String[] args) {
   try {
        final int PORT = 4023;
        ServerSocket server = new ServerSocket(PORT, 100, null);
        System.out.println("Waiting for clients...");

        while (true)
        {                                               
            Socket s = server.accept();             
            System.out.println("Client connected from " + s.getLocalAddress().getHostName());                   
            ServerClient chat = new ServerClient(s);
            Thread t = new Thread(chat);
            t.start();
        }
    } 
    catch (Exception e) 
    {
         e.printStackTrace();
    }
  }    
}

Server Client:

public class ServerClient implements Runnable {

    private Socket socket;  
    public ServerClient(Socket s) {
    socket = s;
 }

@Override
public void run() {
    try {
        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        System.out.println("ObjectInputStream from inputStream created");
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        System.out.println("ObjectOutputStream created");
        String input = (String) ois.readObject();
        System.out.println("received: " + input); 
        oos.writeObject("hello yourself!");
        oos.flush();
        input = (String) ois.readObject();
        System.out.println(input);
        oos.writeObject("this is my second message");
        oos.flush();
        ois.close();
        oos.close();
        socket.close();

    } 
    catch (Exception e)
    {
        e.printStackTrace();
    }   
  }
}  

Client Code:

public class ClientTester {

private final static int PORT = 4023;
private final static int LOCAL_PORT = 4024;
private final static String HOST = //removed for this post;

public static void main(String[] args) throws IOException {
    try {
        Socket s = new Socket(HOST, PORT, InetAddress.getByName(HOST),       LOCAL_PORT);
        s.setSoTimeout(5000);
        System.out.println("You connected to " + HOST);         
        ClientClient client = new ClientClient(s);          
        Thread t = new Thread(client);
        t.start();

    } 
    catch (Exception noServer)
    {
        System.out.println("The server might not be up at this time.");
        System.out.println("Please try again later.");
                    noServer.printStackTrace();
    }
  }
}

Client Client:

public class ClientClient implements Runnable {

private Socket socket;

public ClientClient(Socket s)
{
    socket = s;
}

@Override
public void run() {
    try {
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        System.out.println("ObjectOutputStream from inputStream created");
        oos.writeObject("hello server");
        oos.flush();

        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        System.out.println("ObjectInputStream from inputStream created");
        String input = (String) ois.readObject();
        System.out.println(input);
        oos.writeObject("here is my second message to the server");
        oos.flush();
        input = (String) ois.readObject();
        System.out.println(input);
        oos.close();
        ois.close();
        socket.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    } 
  }
}

The server console says:

run:

Waiting for clients...

Client connected from Ben

The client console says:

run:

You connected to //removed for post

ObjectOutputStream from inputStream created

    java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2320)
    at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2333)
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2804)
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
    at clienttester.ClientClient.run(ClientClient.java:33)
    at java.lang.Thread.run(Thread.java:745)

Can my router's firewall be the culprit? It seems like it is allowing back and forth communication until the ObjectInputStream is being created. Then is it a stupid Java error I'm making? As I said earlier, it works when I remove the router from the system. I'm completely baffled.

This is my first question, from a longtime leacher. Thanks for all your help Stack Overflow!


Solution

  • Sorry for the brief reply, I'm on a mobile, but the problem is that your while loop is in the wrong place. Socket.accept is a blocking operation for a client connection. The client connection is made, then closed,and the code is done. I'll try to expand on the answer when i get to a desktop.