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 把所有东西都扔到我脸上。
我正在尝试编写一个简单的客户端服务器,它将回显用户请求并附加字符串“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 把所有东西都扔到我脸上。