Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java, DatagramPacket receive, how to determine local ip interface

Tags:

java

datagram

Here's simple case when binding to all ip interfaces and specific udp port:

int bindPort = 5555;  // example, udp port number
DatagramSocket socket = new DatagramSocket(bindPort);

byte[] receiveData = new byte[1500];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

...

socket.receive(receivePacket);

How do I know on which ip interface I received packet ?

I can see there is getSocketAddress():

Gets the SocketAddress (usually IP address + port number) of the remote host that this packet is being sent to or is coming from.

but that returns remote ip+port. I would like to know local ip (local port is 5555 in this example).

Is it possible with std. Java libraries ?

like image 556
Igor Delac Avatar asked Feb 26 '14 14:02

Igor Delac


People also ask

Which function is used to get the current machine's IP address?

Python socket module gethostbyname() function accepts hostname argument and returns the IP address in the string format.

What is DatagramSocket Java?

A datagram socket is the sending or receiving point for a packet delivery service. Each packet sent or received on a datagram socket is individually addressed and routed. Multiple packets sent from one machine to another may be routed differently, and may arrive in any order.

Which statement can be used to obtain the IP address of the current machine?

getLocalHost() should give you the IP address of this host.

Is DatagramSocket is a UDP endpoint API?

DatagramSocket is a UDP endpoint API and is used to send and receive datagram packets.


1 Answers

I know this problem. For clarifying the purpose of this: You receive a packet over UDP (normally some kind of discovery implementation) and want return an anwer like ("Dear client, please download the file from http://<wtf-is-my-ip>:8080/thefile.txt"). My machine has three IPs: 127.0.0.1, 192.168.x.x and 10.x.x.x and the goal is to find out that the remote client sent the UDP packet to 192.168.x.x and that this must be the IP which will also work for another connection.

From the weupnp project I found the following code, which is not perfect but worked for me:

    private InetAddress getOutboundAddress(SocketAddress remoteAddress) throws SocketException {
        DatagramSocket sock = new DatagramSocket();
        // connect is needed to bind the socket and retrieve the local address
        // later (it would return 0.0.0.0 otherwise)
        sock.connect(remoteAddress);

        final InetAddress localAddress = sock.getLocalAddress();

        sock.disconnect();
        sock.close();
        sock = null;

        return localAddress;
    }

//DatagramPacket receivePacket;
socket.receive(receivePacket);
System.out.print("Local IP of this packet was: " + getOutboundAddress(receivePacket.getSocketAddress()).getHostAddress);

The code might return the wrong IP if you have multiple IPs in the same network or because of some advanced routing configuration. But so far it's the best I was able to find and it's enough for most situations.

like image 121
Daniel Alder Avatar answered Oct 12 '22 03:10

Daniel Alder