简体   繁体   中英

TCP Sockets Client/Server - server only respondsto first connection from client

I have some simple client and server code, where the client sends some bytes to the server, and the server responds with some bytes. The client prints the received bytes, and then closes the socket.

This works fine the first time the client runs, but subsequent calls get no response.

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

Server code

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

}

Would be grateful for any comments regarding why this is the case. Thank you.

A few things:

This block of code will loop forever until after the client closes his connection:

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

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

Then after the client closes his connection, the subsequent attempt to send "HELLO CLIENT" to the socket will generate an IO exception. That will trigger your server loop to exit.

The easy fix is to adjust your protocol such that the "message" is completed on some sentinel char. In my easy fix, I just adjusted it to break out when a ! was received.

Better to have each client session terminate on an ioexception instead of the entire server block. My refactor of your code:

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

Then adjust your client code's message to be:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM