如何避免 java.net.BindException: Address already in use [英] How to avoid java.net.BindException: Address already in use
本文介绍了如何避免 java.net.BindException: Address already in use的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
以下运行了 1 小时然后关闭:
The following was running for 1 hour and then closed:
public class Mp extends JWindow implements MouseListener, MouseMotionListener {
public static Mp j;
private int serverPort = 0;
private ServerSocket serverSock = null;
private Socket sock = null;
public static void main(final String[] args) throws IOException, InterruptedException, Exception {
j = new Mp();
j.setVisible(true);
j.waitForConnections();
}
public void waitForConnections() {
while (true) {
try {
sock = serverSock.accept();
System.out.println("[TCPMediaHandler]: Accepted new socket");
TCPMediaHandler handler = new TCPMediaHandler(sock);
handler.start();
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
public Mp() throws IOException {
this.serverPort = 38891;
serverSock = new ServerSocket(serverPort);
serverSock.setReuseAddress(true);
//serverSock.setSoTimeout(500);
//serverSock.setSoLinger(true, 0);
System.out.println("[TCPMediaHandler]: Server started");
this.v1.setBackground(Color.BLACK);
this.v1.addMouseListener(this);
/* Close the window */
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
当我重新运行同样的事情时,它会失败并显示 java.net.BindException
:
When I re-run the same thing it fails with a java.net.BindException
:
$ java -cp /var/tmp/dist/Mp.jar test.Mp
Exception in thread "main" java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:353)
at java.net.ServerSocket.bind(ServerSocket.java:336)
at java.net.ServerSocket.<init>(ServerSocket.java:202)
at java.net.ServerSocket.<init>(ServerSocket.java:114)
at test.Mp.<init>(Mp.java)
at test.Mp.main(Mp.java)
大约需要 3 到 4 分钟才能再次成功执行.关机后如何让它立即工作?
It takes about 3 to 4 minutes before it will execute successfully again. How can I make it work immediately after shutting down?
跟进:
$ netstat | grep 38891
tcp 35 0 localhost:38891 localhost:37842 CLOSE_WAIT
tcp 0 0 localhost:34955 localhost:38891 ESTABLISHED
tcp 32 0 localhost:38891 localhost:37824 CLOSE_WAIT
tcp 0 0 localhost:38891 localhost:34955 ESTABLISHED
$ lsof -w -n -i tcp:38891
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
xdg-scree 5254 sun 29u IPv4 231948 0t0 TCP *:38891 (LISTEN)
xdg-scree 5355 sun 29u IPv4 231948 0t0 TCP *:38891 (LISTEN)
xdg-scree 5455 sun 29u IPv4 231948 0t0 TCP *:38891 (LISTEN)
telnet 7058 sun 3u IPv4 242987 0t0 TCP 127.0.0.1:34955->127.0.0.1:38891 (ESTABLISHED)
sleep 9002 sun 29u IPv4 231948 0t0 TCP *:38891 (LISTEN)
sleep 9005 sun 29u IPv4 231948 0t0 TCP *:38891 (LISTEN)
sleep 9008 sun 29u IPv4 231948 0t0 TCP *:38891 (LISTEN)
推荐答案
你会看到你的 setReuseAddress(true) 被调用得太晚了,即在绑定抛出异常之后.
You will see that your setReuseAddress(true) is being called too late i.e. after the bind throws an exception.
您可以通过三个步骤创建一个未绑定的 ServerSocket,使其可重用,然后绑定它.
You can create an unbound ServerSocket, make it reusable and then bind it, in three steps.
ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(12345));
这篇关于如何避免 java.net.BindException: Address already in use的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文