簡體   English   中英

TCP套接字客戶端/服務器-服務器僅響應來自客戶端的第一個連接

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

我有一些簡單的客戶端和服務器代碼,其中客戶端向服務器發送一些字節,服務器以一些字節進行響應。 客戶端打印收到的字節,然后關閉套接字。

客戶端第一次運行時,此方法運行良好,但隨后的調用沒有響應。

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

}

對於有關為什么會這樣的評論,我們將不勝感激。 謝謝。

一些東西:

此代碼塊將永遠循環,直到客戶端關閉其連接為止:

            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".

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM