TCP套接字客户端/服务器-服务器仅响应来自客户端的第一个连接

时间:2018-10-21 20:07:35

标签: java sockets tcp

我有一些简单的客户端和服务器代码,其中客户端向服务器发送一些字节,服务器以一些字节进行响应。客户端打印收到的字节,然后关闭套接字。

这在客户端第一次运行时效果很好,但是随后的调用没有响应。

package sockets.com;

// Client Side
import java.io.*;
import java.net.*;

public class ClientSideTCPSocket {
    public void run() {
        try {
            int serverPort = 4023;
            InetAddress host = InetAddress.getByName("localhost");

            System.out.println("Connecting to server on port " + serverPort);

            Socket socket = new Socket(host, serverPort);

            System.out.println("Just connected to " + socket.getRemoteSocketAddress());


            OutputStream out = socket.getOutputStream();
            InputStream in = socket.getInputStream();

            String s = "HELLO SERVER";
            byte[] bytes = s.getBytes("US-ASCII");

            for (byte b : bytes) {

                out.write(b);

            }

            int ch = 0;
            while ((ch = in.read()) >= 0) {

                System.out.println("Got byte " + ch);
            }

            out.flush();
            out.close();

            socket.close();

        } catch (UnknownHostException ex) {
            ex.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ClientSideTCPSocket client = new ClientSideTCPSocket();
        client.run();
    }
}

服务器代码

package sockets.com;

//Server Side
import java.net.*;
import java.io.*;

public class ServerSideTCPSocket {
    public void run() {
        try {
            int serverPort = 4023;
            ServerSocket serverSocket = new ServerSocket(serverPort);
            serverSocket.setSoTimeout(900000);
            while (true) {
                System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");

                Socket server = serverSocket.accept();
                System.out.println("Just connected to " + server.getRemoteSocketAddress());

                //
                int ch = 0;
                while ((ch = server.getInputStream().read()) >= 0) {

                    System.out.println("Got byte " + ch);
                }
                // Write to output stream

                OutputStream out = server.getOutputStream();

                String s = "HELLO CLIENT";
                byte[] bytes = s.getBytes("US-ASCII");

                for (byte b : bytes) {
                    System.out.println(b);

                    out.write(b);

                }

            }
        } catch (UnknownHostException ex) {

            ex.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ServerSideTCPSocket srv = new ServerSideTCPSocket();
        srv.run();
    }

}

对于有关为何如此的任何评论将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:0)

几件事:

此代码块将永远循环,直到客户端关闭其连接为止:

            while ((ch = server.getInputStream().read()) >= 0) {

                System.out.println("Got byte " + ch);
            }

然后,在客户端关闭其连接之后,随后尝试将“ HELLO CLIENT”发送到套接字将生成IO异常。这将触发服务器循环退出。

最简单的解决方法是调整协议,以便在某些定点字符上完成“消息”。在我的简单修复中,我只是对其进行了调整,使其在收到!时爆发。

最好让每个客户端会话都在ioexception而不是整个服务器块上终止。我对您的代码的重构:

public class ServerSideTCPSocket {

    public void tryCloseSocketConnection(Socket socket) {
        try {
            socket.close();
        }
        catch(java.io.IOException ex) {
        }
    }

    public void processClientConnection (Socket clientConnection) throws java.io.IOException {

        int ch = 0;
        while ((ch = clientConnection.getInputStream().read()) >= 0) {

            System.out.println("Got byte " + ch);
            if (ch == '!') {
                break;
            }
        }
        // Write to output stream

        OutputStream out = clientConnection.getOutputStream();

        String s = "HELLO CLIENT!";
        byte[] bytes = s.getBytes("US-ASCII");

        for (byte b : bytes) {
            System.out.println(b);
            out.write(b);
        }
    }

    public void run() {
        try {
            int serverPort = 4023;
            ServerSocket serverSocket = new ServerSocket(serverPort);
            serverSocket.setSoTimeout(900000);
            while (true) {
                System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");

                Socket clientConnection = serverSocket.accept();

                try {
                    System.out.println("Just connected to " + clientConnection.getRemoteSocketAddress());
                    processClientConnection(clientConnection);
                }
                catch (java.io.IOException ex) {
                    System.out.println("Socket connection error - terminating connection");
                }
                finally {
                    tryCloseSocketConnection(clientConnection);
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ServerSideTCPSocket srv = new ServerSideTCPSocket();
        srv.run();
    }
}

然后将客户代码的消息调整为:

        String s = "HELLO SERVER!";  // the exclamation point indicates "end of message".