write socket getoutputstream example java linux networking tcp

socket - Cómo evitar java.net.BindException: dirección ya en uso



sockets example java (2)

Tuve un problema similar en uno de mis programas, pero terminó que realmente estaba ejecutando una instancia del programa de mi IDE, que no había notado. Siempre revise dos veces que no haya algo ejecutándose en segundo plano.

Lo siguiente se ejecutó durante 1 hora y luego se cerró:

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); } }); }

Cuando vuelvo a ejecutar lo mismo, falla con una 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)

Tarda de 3 a 4 minutos antes de que se ejecute nuevamente con éxito. ¿Cómo puedo hacer que funcione inmediatamente después de apagarlo?

Seguir:

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


Verá que su setReuseAddress (verdadero) se está llamando demasiado tarde, es decir, después de que el enlace arroja una excepción.

Puede crear un ServerSocket independiente, hacerlo reutilizable y luego enlazarlo, en tres pasos.

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