gpt4 book ai didi

java - "java.net.BindException: Address already in use"尝试使用与前一个线程相同的新线程创建套接字时

转载 作者:可可西里 更新时间:2023-11-01 02:43:53 26 4
gpt4 key购买 nike

我正在使用 Java 进行客户端-服务器模拟,其中客户端(线程)连接到服务器以获取一些数据。几秒钟后,需要杀死随机选择的客户端(线程)之一。我关闭了它用于与服务器通信的套接字并让他死了(通过退出 run() 方法)。问题是当新创建的线程试图创建与前一个线程相同的套接字(相同的地址和相同的端口)以连接到服务器时,我得到:

java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:374)
at java.net.Socket.bind(Socket.java:627)
at java.net.Socket.<init>(Socket.java:423)
at java.net.Socket.<init>(Socket.java:319)

创建套接字的代码:

private void createNewSocket(InetAddress sIP, int sPort, 
InetAddress cIP, int cPort) {
try {
socket = new Socket(sIP, sPort, cIP, cPort);
} catch (IOException e) {
e.printStackTrace();
System.err.println("Socket unsuccessfully created");
}
try {
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));

out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);

} catch (IOException e) {
e.printStackTrace();
try {
socket.close();
} catch (IOException e2) {
System.err.println("Socket unsuccessfully closed");
}
}
}

public void run() {

createNewSocket(gprsServerIP, Util.PORT_SERVER_PORT,
clientIP, sendPort);

out.println(REQUEST);
try {
serverPort = Integer.parseInt(in.readLine());
TCPClient.serverPort[clientID] = serverPort;
System.out.println("Server port: " + serverPort + '\n' +
"Send port: " + sendPort + '\n');
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
System.err.println("Socket unsuccessfully closed");
}
}

while (true) {

if (clientID == TCPClient.selectedID) {

TCPClient.selectedID = -1;

createNewSocket(gprsServerIP, Util.PORT_SERVER_PORT,
clientIP, sendPort);

out.println(FREE_PORT + serverPort);
try {
socket.close();
} catch (IOException e2) {
System.err.println("Socket unsuccessfully closed");
}
//System.out.println(socket.isClosed());
System.out.println("Port:" + serverPort + " is free");
TCPClient.id[clientID] = -1;
break;
}
}
clientCount--;

}

最佳答案

很可能客户端套接字仍在 CLOSE_WAIT or TIME_WAIT status 中.操作系统确保在另一个应用程序可以重新使用它之前,所有数据都已通过套接字传送。否则,新客户端可能会得到先前连接遗留下来的垃圾重复数据包。

我建议您的客户使用一系列端口而不是一个常量。然后他们可以使用范围中的下一个端口并在到达范围末尾时循环。

但是,如果您不需要设置客户端端口,那么您根本不应该通过将端口 0 传递给 Socket 来在代码中设置客户端端口。在这种情况下,JDK 和操作系统会做正确的事情并为您选择合适的自由端口。

引自wikipedia :

CLOSE-WAIT: The server receives notice from the local application that it is done. The server sends its fin to the client.

TIME-WAIT: Represents waiting for enough time to pass to be sure the remote peer received the acknowledgment of its connection termination request. According to RFC 793 a connection can stay in TIME-WAIT for a maximum of four minutes known as a MSL (maximum segment lifetime).

关于java - "java.net.BindException: Address already in use"尝试使用与前一个线程相同的新线程创建套接字时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12206655/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com