Linux 如何避免 java.net.BindException: Address already in use
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9762859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to avoid java.net.BindException: Address already in use
提问by
The following was running for 1 hour and then closed:
以下运行了 1 小时,然后关闭:
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);
}
});
}
When I re-run the same thing it fails with a java.net.BindException
:
当我重新运行同样的事情时,它失败了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)
It takes about 3 to 4 minutes before it will execute successfully again. How can I make it work immediately after shutting down?
大约需要 3 到 4 分钟才能再次成功执行。如何在关闭后立即使其工作?
Follow up:
跟进:
$ 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)
采纳答案by Peter Lawrey
You will see that your setReuseAddress(true) is being called too late i.e. after the bind throws an exception.
你会看到你的 setReuseAddress(true) 被调用得太晚了,即在绑定抛出异常之后。
You can create an unbound ServerSocket, make it reusable and then bind it, in three steps.
您可以通过三个步骤创建一个未绑定的 ServerSocket,使其可重用,然后绑定它。
ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(12345));
回答by Lauripops
I had a similar problem in one of my programs, but it ended up that I was just actually running an instance of the program from my IDE - which I hadn't noticed. Always double check there isn't something running in the background.
我在我的一个程序中遇到了类似的问题,但最终我实际上只是从我的 IDE 中运行了该程序的一个实例——我没有注意到这一点。始终仔细检查是否有任何东西在后台运行。