在Java中,客户端关闭后服务端会重复输出客户端最后传递的信息,这是因为在TCP协议中,客户端关闭连接时,操作系统并不会立即关闭连接,而是会发送一个FIN包给服务端,告诉服务端客户端已经关闭连接。服务端接收到FIN包后,会回复一个ACK包给客户端,告诉客户端已经收到关闭连接的请求。但是,服务端并不会立即关闭连接,而是会等待一段时间,称为TIME_WAIT状态,以确保客户端收到了ACK包。在这个状态下,服务端仍然可以接收到客户端发送的数据,因此会重复输出客户端最后传递的信息。
解决这个问题的方法是在服务端代码中判断客户端是否已经关闭连接,如果已经关闭连接,则不再输出客户端传递的信息。可以使用Socket类的isClosed()方法或isConnected()方法来判断客户端是否已经关闭连接。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端已启动,等待客户端连接...");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("客户端已连接,IP地址为:" + socket.getInetAddress().getHostAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (socket.isClosed()) {
break;
}
System.out.println("客户端传递的信息为:" + line);
}
System.out.println("客户端已关闭连接");
socket.close();
}
}
}