tags:

views:

184

answers:

3

I have an application which uses UDP connection, now when i try to run the app more than once its throwing me an exception

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

but in my another app, which uses tcp connection, i can open two instance of the same app and its working fine. why this error only with UDP connection?

Edit:

TCP socket:

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

If i create TCP socket like above,with same port, it is not throwing any error. but if i do this with UDP Socket it throwing me an exception, why?

+1  A: 

To my knowledge using bind() with the same port number on multiple sockets is undefined. On UDP there is no underlying connection mechanism as with TCP. This means that even though you have sent a packet to a particular IP address on one of the sockets it did not change anything on the status of your socket

giri
so, do u mean that we cant create two udp socket with same port?
swift
A: 

Are you sure that the TCP application really does a bind with a non-zero port number? It shouldn't work for TCP either. The purpose of port numbers is to identify which running application instance to route the traffic to; if two applications were to each bind two sockets to the same port number, that routing becomes impossible, which is why it's an error.

unwind
+1  A: 

It has to do with the difference between TCP and UDP. When you create a TCP socket you are creating a synchronous client connection to the port on another machine, and when you connect to an address you actually get a local port on the socket as well. So in your example code the two sockets created might be

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

Note that while they remote address is the same, the local address has different ports, which is why this is allowed. So here the local an remote machines can reliably send the data back and forth using the established ports.

For UDP this is not the case (I am assuming you are using DatagramSocket). Since UDP is asynchronous (as opposed to synchronous like TCP), to recieve data you are not creating a binding to another specific machine, so for example if you were to try

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

the udp socket does not know where the data is coming from so there can not be a unique mapping like TCP, also unlike TCP the port you specify is your machine's port, not a remote machine port.

Another way to think of it when you create a UDP socket it is like creating a TCP server socket. When you create a TCP server socket it is waiting for a connection to come from some machine but that machine is unknown and when you create a TCP server socket the port you specify is a local port:

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

Again like UDP this will create a bind exception because the port is for the local machine and the mappings are no longer unique. But when you accept a connection on a server socket the remote machine comes into play to make the socket unique, just as when you create a Socket to a remote machine:

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

Note that although the local address is the same, the remote addresses for the sockets are different, and hence the total mapping (localip:port<->remoteip:port) is now unique.

So in a way you can think of a UDP socket as kind of like a TCP server socket and that is why you have to bind it to a unique port.

M. Jessup