2012-03-18 123 views
2

以下是運行1小時,然後關閉:如何避免java.net.BindException:地址已在使用

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

$ 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分鐘才能再次執行成功。如何在關閉後立即使其工作?

追問:

$ 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) 

回答

11

你會看到你的setReuseAddress(真)被稱爲太晚即綁定拋出異常後。

您可以創建一個未綁定的ServerSocket,使其可重用,然後綁定它,分三個步驟。

ServerSocket ss = new ServerSocket(); 
ss.setReuseAddress(true); 
ss.bind(new InetSocketAddress(12345)); 
+0

謝謝!我已經根據你的偉大建議進行了嘗試。但我仍然無法修復它。請參閱上面我的編輯後續部分。還有一些顯示ESTABLISHED,但實際上我沒有,甚至我的應用程序被終止。但是我仍然可以執行'telnet localhost thatport' – YumYumYum 2012-03-18 22:53:10

+1

@YumYumYum在CLOSE_WAIT狀態下存在一個端口表示應用程序在您使用netstat時仍在運行。 – EJP 2012-03-18 23:09:37

+0

在我的方案中,我並不真正關心端口號,因此可以使用 ServerSocket myServer = new ServerSocket(0); final int port = myServer.getLocalPort(); – tobi42 2016-10-06 14:28:13

1

我在節目中的一個也有類似的問題,但它結束了,我只是在實際運行從我的IDE程序的實例 - 我沒有注意到。總是仔細檢查,沒有東西在後臺運行。

相關問題