Java 套接字握手正常,但没有其他数据。路由器或 Java(或我自己)应该受到指责?

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

我正在尝试在 Java 中建立 server/client 连接。 我已经将我的 PC 直接连接到 DSL,它可以通过 Windows 10 防火墙正常工作。我重新连接到我的 TP-Link Archer C9 路由器,虚拟服务器设置为端口 4023 和 4024。我在客户端得到一个 SocketTimeoutException

当我过滤端口 4023 时,Wireshark 在客户端握手后给了我一堆 TCP 重传说 'hello server':

服务器代码:

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();
    }
  }    
}

服务器客户端:

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();
    }   
  }
}  

客户代码:

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();
    }
  }
}

客户客户:

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();
    } 
  }
}

服务器控制台显示:

run:

Waiting for clients...

Client connected from Ben

客户端控制台显示:

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)

我路由器的防火墙会是罪魁祸首吗?在创建 ObjectInputStream 之前,它似乎允许来回通信。 那我犯的是愚蠢的 Java 错误吗?正如我之前所说,当我从系统中删除路由器时它会起作用。我完全莫名其妙。

这是我的第一个问题,来自一位长期学习者。感谢您对 Stack Overflow 的所有帮助!

抱歉简短的回复,我在手机上,但问题是你的 while 循环在错误的地方。 Socket.accept 是客户端连接的阻塞操作。建立客户端连接,然后关闭,代码完成。当我进入桌面时,我会尝试扩展答案。