[英]BufferedReader Pending for Request/Response Socket Connection
我正在尝试构建一个简单的请求/响应服务器。
客户端向服务器发送消息。 然后,服务器向客户端响应消息。
服务器端代码
package com.techoffice.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
public class TcpServerAppl {
static int port = 1010;
static ServerSocket serverSocket;
static {
try {
serverSocket = ServerSocketFactory.getDefault().createServerSocket(port);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
System.out.println("Server is running on " + port);
while(true){
Socket socket = null;
try{
socket = serverSocket.accept();
System.out.println("Someone is connecting to the server");
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(os);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
// read message from client
String line = bufferedReader.readLine();
while(line != null && line.length() > 0){
System.out.println(line);
line = bufferedReader.readLine();
}
// reader.close();
// send message to client
System.out.println("Server starts sending message to client");
printWriter.println("This is a message sent from server");
printWriter.flush();
// printWriter.close();
} catch(Exception e){
System.err.println(e.getMessage());
} finally {
if (socket != null){
try {
socket.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
}
}
}
客户端代码
package com.techoffice.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
public class TcpClientAppl {
public static void main(String[] args) throws UnknownHostException, IOException{
// start socket connection
Socket socket = SocketFactory.getDefault().createSocket("localhost", 1010);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// send message to server
printWriter.println("Send Message From Client" );
printWriter.flush();
// printWriter.close();
// read message from server
System.out.println("Client starts reading from Server");
String line = bufferedReader.readLine();
while(line != null && line.length() > 0){
System.out.println(line);
line = bufferedReader.readLine();
}
// bufferedReader.close();
// close scoket connection
socket.close();
}
}
服务器在缓冲读取器处被阻塞。 但是,如果我尝试通过关闭客户端中的打印写入器来关闭缓冲读取器,客户端会抛出“连接关闭”异常。
众所周知,在 PrintWriter 或 BufferedReader 中关闭将关闭套接字连接。
更新
指定请求/消息结束将是解决方案之一。 但在这种情况下,我不希望请求结束。 无论请求中没有多少行,我只想对请求做出响应。
客户端抛出“连接关闭”异常
不,它没有。 如果取消对printWriter.close()
行的注释,它将抛出异常“套接字已关闭”。
但是对于你真正的问题。 服务器在发送任何内容之前读取行直到流结束:在对等方关闭连接之前永远不会发生流结束; 除上述情况外,对等方没有关闭连接; 所以它永远不会发送任何东西,只是停留在readLine()
; 所以客户端也将永远阻塞在readLine()
。
由于这显然是一个回显服务器,它应该在接收到每一行时回显。
问题是缺少客户端抛出的异常。 也许尝试在您的通信完成后关闭服务器端的所有内容(读取器、写入器)。 顺便提一句。 你不需要在调用 close 之前调用flush。 您也可以在服务器端使用带有套接字的 try-catch-withResources
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.