如何避免 java.net.BindException: Address already in use [英] How to avoid java.net.BindException: Address already in use

查看:21
本文介绍了如何避免 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆