&引用;java.net.BindException:地址已在使用中;当尝试使用新线程创建与前一个相同的套接字时
我正在用Java进行客户机-服务器模拟,其中客户机(线程)连接到服务器以获取一些数据。几秒钟后,需要终止随机选择的客户机(线程)之一。我关闭了它用来和服务器通信的套接字,让他死了(通过退出run()方法)。问题是,当新创建的线程试图创建与前一个用于连接到服务器的套接字相同的套接字(相同的地址和端口)时,我得到:&引用;java.net.BindException:地址已在使用中;当尝试使用新线程创建与前一个相同的套接字时,java,multithreading,sockets,networking,tcp-ip,Java,Multithreading,Sockets,Networking,Tcp Ip,我正在用Java进行客户机-服务器模拟,其中客户机(线程)连接到服务器以获取一些数据。几秒钟后,需要终止随机选择的客户机(线程)之一。我关闭了它用来和服务器通信的套接字,让他死了(通过退出run()方法)。问题是,当新创建的线程试图创建与前一个用于连接到服务器的套接字相同的套接字(相同的地址和端口)时,我得到: java.net.BindException: Address already in use at java.net.PlainSocketImpl.socketBind(Nat
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)
当进程非自然终止时,有时端口不会立即解除绑定,您必须等待几分钟才能使端口可用。如果可能,您的程序应该正常地失败(即,即使它必须被终止,关闭钩子也应该关闭套接字)。当进程非自然地终止时,有时端口没有立即解除绑定,您必须等待几分钟才能使端口可用。如果可能的话,您的程序应该正常地失败(即,即使必须终止程序,关闭挂钩也应该关闭套接字)。客户端套接字可能仍在运行。操作系统正在确保在其他应用程序重新使用之前,所有数据都已通过套接字传递。否则,新客户机可能会从以前的连接中得到重复的垃圾数据包 我建议您的客户使用一系列端口,而不是常量端口。然后,他们可以使用范围内的下一个端口,并在到达范围末端时循环 但是,如果不需要设置客户端端口,则不应通过将端口0传递到
Socket
来在代码中设置客户端端口。在这种情况下,JDK和操作系统将做正确的事情,并为您选择合适的空闲端口
引自:
近距离等待:
服务器收到本地应用程序发出的完成通知。服务器将其fin发送到客户端
等待时间:
表示等待足够的时间以确保远程对等方收到其连接终止请求的确认。根据RFC 793,连接最多可以等待四分钟,称为MSL(最大段生存期)
客户机套接字很可能仍在。操作系统正在确保在其他应用程序重新使用之前,所有数据都已通过套接字传递。否则,新客户机可能会从以前的连接中得到重复的垃圾数据包 我建议您的客户使用一系列端口,而不是常量端口。然后,他们可以使用范围内的下一个端口,并在到达范围末端时循环 但是,如果不需要设置客户端端口,则不应通过将端口0传递到
Socket
来在代码中设置客户端端口。在这种情况下,JDK和操作系统将做正确的事情,并为您选择合适的空闲端口
引自:
近距离等待:
服务器收到本地应用程序发出的完成通知。服务器将其fin发送到客户端
等待时间:
表示等待足够的时间以确保远程对等方收到其连接终止请求的确认。根据RFC 793,连接最多可以等待四分钟,称为MSL(最大段生存期)
连接时不必指定客户端ip和客户端端口。。如果你忽略它们,它会选择一个可用的端口,而不是你可以为
run()
方法发布你的代码吗?我需要使用它们,因为客户端是从Ubuntu中的VM和Windows 7上的服务器上运行的,我需要指定客户端端口和IP以用于其他目的。“其他一些目的”例如?可能您的程序异常关闭,套接字仍然绑定到进程。操作系统将在几分钟后启动该进程。通过ServerSocket.setReuseAddress(true)可以避免这种情况,连接时不必指定客户端ip和客户端端口。。如果你忽略它们,它会选择一个可用的端口,而不是你可以为run()
方法发布你的代码吗?我需要使用它们,因为客户端是从Ubuntu中的VM和Windows 7上的服务器上运行的,我需要指定客户端端口和IP以用于其他目的。“其他一些目的”例如?可能您的程序异常关闭,套接字仍然绑定到进程。操作系统将在几分钟后启动该进程。你可以通过ServerSocket.setReuseAddress(true)来避免这种情况。他是完全正确的。他为什么不受欢迎?他完全正确。为什么他越来越不受欢迎?
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--;
}