2010-05-05 14 views
7

tengo una aplicación que utiliza la conexión UDP, ahora cuando trato de ejecutar la aplicación más de una vez su yo una excepción¿Pueden dos puertos UDP diferentes en un sistema enlazar el mismo puerto?

java.net.BindException: Address already in use: Cannot bind 

pero en mi otra aplicación, que utiliza la conexión TCP, puedo abrir dos instancias de la misma aplicación y funciona bien. ¿por qué este error solo con la conexión UDP?

Editar:

TCP socket: 

Socket clientSocket= new Socket(ipAddress, 8000); 
Socket clientSocket1= new Socket(ipAddress, 8000); 

Si creo socket TCP como el anterior, con mismo puerto, no es tirar cualquier error. pero si hago esto con Socket UDP es lanzándome una excepción, ¿por qué?

Respuesta

1

Que yo sepa, usar bind() con el mismo número de puerto en múltiples sockets no está definido. En UDP no hay un mecanismo de conexión subyacente como con TCP. Esto significa que, aunque haya enviado un paquete a una dirección IP particular en uno de los enchufes, no cambió nada en el estado de su socket

+0

Entonces, ¿quiere decir que no podemos crear dos zócalos udp con el mismo puerto? – swift

1

¿Está seguro de que la aplicación TCP realmente se une con un no- ¿número de puerto cero? Tampoco debería funcionar para TCP. El propósito de los números de puerto es identificar a qué instancia de la aplicación en ejecución se enrutará el tráfico; si se unen dos aplicaciones para unir dos tomas con el mismo número de puerto, ese enrutamiento se vuelve imposible, por lo que es un error.

13

Tiene que ver con la diferencia entre TCP y UDP. Cuando crea un socket TCP está creando una conexión de cliente síncrono con el puerto en otra máquina, y cuando se conecta a una dirección, también obtiene un puerto local en el socket. Así que en el código de ejemplo, los dos conectores creados podría ser

clientSocket = localhost:2649 <-> ipAddress:8000 
clientSocket1 = localhost:2650 <-> ipAddress:8000 

Tenga en cuenta que mientras que la dirección remota es la misma, la dirección local tiene diferentes puertos, por lo que está permitido. De modo que aquí, las máquinas locales y remotas pueden enviar los datos de manera confiable utilizando los puertos establecidos.

Para UDP este no es el caso (supongo que está utilizando DatagramSocket). Dado que UDP es asíncrona (en contraposición a modo síncrono como TCP), para recibir los datos que no está creando una unión a otra máquina específica, por lo que por ejemplo, si se va a tratar

DatagramSocket udp1 = new DatagramSocket(8000); // = localhost:8000 <-> ? 
DatagramSocket udp2 = new DatagramSocket(8000); // = localhost:8000 <-> ? 

el socket UDP no sabe dónde está el los datos provienen de modo que no puede haber una asignación única como TCP, también a diferencia de TCP, el puerto que especifique es el puerto de su máquina, no un puerto de máquina remota.

Otra forma de pensarlo cuando crea un socket UDP es como crear un socket de servidor TCP. Cuando se crea un socket de servidor TCP que se espera de una conexión a venir de alguna máquina, pero esa máquina es desconocido y cuando se crea un socket de servidor TCP en el puerto que especifique es un puerto local:

ServerSocket ss1 = new ServerSocket(8000); // = localhost:8000 <-> ? 
ServerSocket ss2 = new ServerSocket(8000); // = localhost:8000 <-> ? 

vez más, como UDP esto creará una excepción de vinculación porque el puerto es para la máquina local y las asignaciones ya no son únicas.Pero cuando se acepta una conexión en un socket servidor de la máquina remota entra en juego para hacer la toma única, al igual que cuando se crea un socket a una máquina remota:

Socket s1 = ss1.accept();// localhost:8000 <-> remoteIp1:12345 
Socket s2 = ss1.accept();// localhost:8000 <-> remoteIp2:54321 

en cuenta que aunque la dirección local es la misma , las direcciones remotas para los sockets son diferentes, y por lo tanto, la asignación total (localip: puerto < -> remoteip: port) ahora es única.

Entonces, de alguna manera, puede pensar en un socket UDP como algo así como un socket de servidor TCP y es por eso que tiene que vincularlo a un puerto único.

Cuestiones relacionadas