Java 套接字客户端服务器响应应用程序

Java socket client server response application

我正在尝试编写一个简单的客户端服务器,它将回显用户请求并附加字符串“Response :”。

他们是我看过的类似问题,但我无法理解发生了什么。我正在尝试写这篇文章,但无法让它发挥作用。 主要是我对正在发生的事情很困惑。

我已尽我所能评论我的代码,以尝试解释我认为正在发生的事情。 我不确定问题是什么,当我 运行 输入一条消息时我没有收到回复

客户端

public class Client {

public void go() {

    try {
        //Create a Socket with ip and port number
        Socket s = new Socket("127.0.0.1", 4242);

        //Get input from user
        Scanner in = new Scanner(System.in);
        System.out.println("Please enter a message");
        String clientMessage = in.nextLine();

        //Make a printwriter and write the message to the socket
        PrintWriter writer = new PrintWriter(s.getOutputStream());
        writer.write(clientMessage);
        writer.close();

        //StreamReader to read the response from the server
        InputStreamReader streamReader = new InputStreamReader(s.getInputStream());
        BufferedReader reader = new BufferedReader(streamReader);

        //Get the response message and print it to console
        String responseMessage = reader.readLine();
        System.out.println(responseMessage);
        reader.close();

    } catch (IOException ex) {
        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
    }

}

public static void main(String[] args) {
    Client c = new Client();
    c.go();
}

}

服务器

public class Server {

public void go() {
    try {
        //Make a ServerSocket to listen for message
        ServerSocket ss = new ServerSocket(4242);

        while (true == true) 
        {
            //Accept input from socket
            Socket s = ss.accept();

            //Read input from socket
            InputStreamReader streamReader = new InputStreamReader(s.getInputStream());
            BufferedReader reader = new BufferedReader(streamReader);                
            String message = reader.readLine();

            //get the message and write it to the socket as response
            PrintWriter writer = new PrintWriter(s.getOutputStream());
            String response = "Response : " + message;
            writer.println(response);
            writer.close();

        }
    } catch (IOException ex) {
        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public static void main(String[] args) {
    Server server = new Server();
    server.go();
}

}

从客户端代码中删除 sock 和 serverSock 并使用 s.getInputStream。

套接字在两端都是双向的,所以就像在发送回消息时在服务器上不需要一个新的一样,在客户端接收它也不需要一个新的。

编辑

此外,"Closing the returned OutputStream will close the associated socket."(getOutputSteam 的文档),所以不要关闭编写器,只需刷新即可。

服务器可以以其当前形式工作,客户端开始进行较小的更改(println 和刷新):

//Create a Socket with ip and port number
Socket s = new Socket("127.0.0.1", 4242);

//Get input from user
Scanner in = new Scanner(System.in);
System.out.println("Please enter a message");
String clientMessage = in.nextLine();

//Make a printwriter and write the message to the socket
PrintWriter writer = new PrintWriter(s.getOutputStream());
writer.println(clientMessage); // <- println
writer.flush();                // <- flush

//StreamReader to read the response from the server
InputStreamReader streamReader = new InputStreamReader(s.getInputStream());
BufferedReader reader = new BufferedReader(streamReader);

//Get the response message and print it to console
String responseMessage = reader.readLine();
System.out.println(responseMessage);
reader.close();
writer.close();                // <- new location for close (*)

(*) 在主 try 块中使用 close 被认为是不安全的,因为只要有异常,这些行就不会 运行 (另外,如果你使用任何类型的智能 IDE,它可能指出 Socket 对象本身和 Scanner 根本没有关闭)。延伸阅读:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

所以最后客户宁愿看起来像这样,遵循更 "contemporary" 的方法:

try (
    Socket s = new Socket("127.0.0.1", 4242);
    Scanner in = new Scanner(System.in);
    PrintWriter writer = new PrintWriter(s.getOutputStream());
    InputStreamReader streamReader = new InputStreamReader(s.getInputStream());
    BufferedReader reader = new BufferedReader(streamReader);
) {
    //Create a Socket with ip and port number

    //Get input from user
    System.out.println("Please enter a message");
    String clientMessage = in.nextLine();

    //Make a printWriter and write the message to the socket
    writer.println(clientMessage);
    writer.flush();

    //StreamReader to read the response from the server

    //Get the response message and print it to console
    String responseMessage = reader.readLine();
    System.out.println(responseMessage);
} catch (IOException ex) {
    ex.printStackTrace(); // (**)
}

(**) 我绝对确定您没有查看日志,否则您会知道过早关闭了Socket。在试验小段代码时,我不建议将异常隐藏在晦涩的日志中。事实上,我通常只是到处写 "throws Exception"(包括 main,这也是可能的),然后让 JRE 把所有东西都扔到我脸上。