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

时间:2017-05-03 19:31:29

标签: java sockets server serversocket

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

他们是类似的问题,我已经看过,但我无法理解发生了什么。我想写这个,但不能让它工作。 主要是因为我对正在发生的事情感到非常困惑。

我已尽可能地评论我的代码,以便尝试解释我认为正在发生的事情。 我不知道当我运行这个并输入一条消息我没有得到回复时问题是什么

客户端

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

}

服务器

LeftCell

1 个答案:

答案 0 :(得分:2)

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

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

修改

此外,“关闭返回的OutputStream将关闭相关的套接字。” (getOutputSteam的文档),所以不要关闭编写器,只需刷新它。

服务器可以以当前形式工作,并且客户端开始处理次要更改(println和flush):

//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对象本身,扫描仪根本没有关闭。进一步阅读:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

所以最后客户看起来更像这样,遵循更“现代”的方法:

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

(**)我绝对相信你没有检查过日志,否则你就会知道过早关闭套接字。在尝试使用小块代码时,我不建议在异常日志中隐藏异常。事实上,我通常只是在任何地方写出“抛出异常”(包括main,这也是可能的)并且让JRE将所有东西都抛到我脸上。