Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: java.net.DatagramSocket.bind: Invalid Argument Exception

Background: I'm writing a simple UDP application to ping a beta server I manage every minute or so to tell me it is still up and running (I can't enable ping on the server for those that are wondering). I plan to run this on my phone to warn me when the server is no longer responding.

I'm trying to use the seemingly simple java.net.DatagramSocket as such:

    try
    {
        socket = new DatagramSocket();
        socket.bind(null);
    } 
    catch (SocketException e)
    {
        System.out.println(e.toString());
        throw e;
    }

Let me also say that I have enabled the Internet permissions through the android manifest and if I remove the uses clause to do so, I get a permissions error so I'm sure that is working OK. When I download this code to an Android Virtual Device (AVD) and execute it, on the call to bind() I am presented with this exception:

03-17 19:07:39.401: INFO/System.out(338): java.net.BindException: Invalid argument

According to this documentation, the null argument is correct:

public void bind (SocketAddress localAddr)

Since: API Level 1

Binds this socket to the local address and port specified by localAddr. If this value is null any free port on a valid local address is used.

But not trusting documentation, I decided to enumerate the IP addresses on my device like this:

    ArrayList<NetworkInterface>  allInterfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
    
    NetworkInterface eth = allInterfaces.get(0);
                
    InetSocketAddress addr = new InetSocketAddress(eth.getInetAddresses().nextElement(), port);
    
    try
    {
        socket = new DatagramSocket();
        socket.bind(addr);
    } 
    catch (SocketException e)
    {
        System.out.println(e.toString());
        throw e;
    }

When I step through the code, it works great and I can see the two IP address on the AVD but I get the exact same exception on the bind() call. Does anybody out there see what i might be missing? I will continue to research and hopefully post a solution to my own problem, but I am hoping somebody out there will be able to shortcut this for me.

like image 799
Lance Avatar asked Mar 18 '11 02:03

Lance


1 Answers

[Edited: if you saw my previous response I made the classic debugging mistake of changing two variable in one test and it was the other one that solved my problem.]

I found the problem. It is the way I'm declaring the DatagramSocket that appears to cause problems. If I use a DatagramChannel to open the DatagramSocket in the following way then the bind() call is successful.

      DatagramChannel channel = DatagramChannel.open();
      DatagramSocket socket = channel.socket();
like image 149
Lance Avatar answered Nov 15 '22 21:11

Lance