我有一个示例套接字程序。客户端只发送数字,服务器回送它们。
客户端:
public class Client {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Client(String hostname, int port) throws IOException {
socket = new Socket(hostname, port);
//Create a BufferedReader with buffer size of 1
in = new BufferedReader(new InputStreamReader(socket.getInputStream()), 1);
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
}
public void sendRequest(String x) throws IOException {
out.print(x + "\n");
out.flush();
}
public void close() throws IOException {
in.close();
out.close();
socket.close();
}
public String getReply() throws IOException {
String reply = in.readLine();
return reply;
}
public static void main(String[] args) {
try {
Client client = new Client("localhost", 4949);
for (int i = 0; i < 100000; i++){
System.err.println("Sending: "+i);
client.sendRequest(String.valueOf(i));
}
for (int i = 0; i < 100000; i++){
client.getReply();
}
client.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
服务器:
public class Server {
private ServerSocket serverSocket;
public Server(int port) throws IOException {
serverSocket = new ServerSocket(port);
}
private void handle(Socket socket) throws IOException {
System.err.println("client connected");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Create a PrintWriter with buffer size 1
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()), 1));
try {
for (String line = in.readLine(); line != null; line = in.readLine()) {
out.print(line + "\n");
out.flush();
}
} finally {
out.close();
in.close();
}
}
public void serve() throws IOException {
while (true) {
// block until a client connects
Socket socket = serverSocket.accept();
try {
handle(socket);
} catch (IOException ioe) {
ioe.printStackTrace(); // but don't terminate serve()
} finally {
socket.close();
}
}
}
public static void main(String[] args) {
try {
Server server = new Server(4949);
server.serve();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这似乎是一个显而易见的问题,但为什么客户端的输入缓冲区没有填满并导致死锁?客户端在阅读任何回复之前会发送10000个号码。这不会导致客户端的接收缓冲区填满,也会导致服务器的发送缓冲区填满吗?我甚至将BufferedReader和BufferedWriter的缓冲区大小尽可能小。但是,当我运行此代码时,没有死锁。
答案 0 :(得分:2)
因为您忽略了发送方处的套接字发送缓冲区的存在,以及接收方处的套接字接收缓冲区。它们位于内核中,它们可以清楚地保存服务器之间的所有输出。