I'm implementing a Discover process that:
- Open a UDP socket to listen for broadcast response on a given port
- Send some requests (and expect later response)
- Close the UDP socket after a given period of time
The first call works. But other call get a bind error. Address already in use: bind
I'm running Windows 7. I did some tests and found that after a channel.close(); Netstat still gives:
netstat -a -b -sp udp | grep 55224
UDP 0.0.0.0:55224 :
So the udp port is still opened at the OS level
I searched the web and it may be a leak at the os level : Some java Datagram Socket questions
I ran 2 tests one using NIO channel and one without (from a test found on the web). I reproduce my error with the NIO version but it works if I don`t use NIO.
I anybody can point me how I can make it works with NIO. The targetted platform is Android where I dont wan
t to always listen for broadcast but only for repetitive period of time.
TEST SOCKET
public void testConnectCloseWithSocket() {
long tCumulative = 0;
int errAt = -1;
System.out.println("start...");
for (int i = 0; i < 4000; i++) {
try {
errAt = i;
DatagramSocket result = new DatagramSocket(null);
result.bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
result.close();
//success at last
tCumulative = 0;
} catch (Exception e) {
System.out.println("Error (at="+errAt+") (waited="+tCumulative+"ms): " + e.getMessage());
tCumulative+=50;
try {
Thread.sleep(50);
} catch (InterruptedException e1) {
}
i--;
}
}
System.out.println("end...");
}
RESULT SOCKET<
start... Error (at=1319) (waited=0ms): Address already in use: Cannot bind
Error (at=1438) (waited=0ms): Address already in use: Cannot bind
Error (at=1587) (waited=0ms): Address already in use: Cannot bind
Error (at=1740) (waited=0ms): Address already in use: Cannot bind
end...
I did get some errors but the socket get closed properly... which is oki for my needs
TEST WITH CHANNEL
public void testConnectCloseWithChannel() {
long tCumulative = 0;
int errAt = -1;
System.out.println("start...");
for (int i = 0; i < 4000; i++) {
try {
errAt = i;
Selector selector = Selector.open();
DatagramChannel channel = DatagramChannel.open();
channel.configureBlocking(true);
channel.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
SelectionKey clientKey = channel.register(selector, SelectionKey.OP_READ);
clientKey.cancel();
channel.close();
//success at last
tCumulative = 0;
} catch (Exception e) {
System.out.println("Error (at="+errAt+") (waited="+tCumulative+"ms): " + e.getMessage());
tCumulative+=50;
try {
Thread.sleep(tCumulative);
} catch (InterruptedException e1) {
}
i--;
}
}
System.out.println("end...");
}
NOTE: It the channel.register is commented the test works ..
RESULT WITH CHANNEL
start... Error (at=0) (waited=0ms): null Error (at=0) (waited=50ms): Address already in use: bind
Error (at=0) (waited=100ms): Address already in use: bind
Error (at=0) (waited=150ms): Address already in use: bind ...
Thanks for any help