I recently had a task where I needed to inform a docker image of the host OS’ IP address. (The docker image needed to make an HTTP call to the host machine, for testing purposes.) However, it’s not trivial to find code to actually get a host machine’s IP address. Here’s some code in Kotlin (and in Java) to accomplish the task; I can’t say it’s perfect (and won’t) but it worked for me, and hopefully this can serve as a tentpole for perhaps better code.
There are two pieces of code here; both eliminate the 10.*.*.*
network. If you don’t need that network to be eliminated, well, remove that line.
Kotlin
import java.net.NetworkInterface fun getAddress(): String { return NetworkInterface.getNetworkInterfaces().toList().flatMap { it.inetAddresses.toList() .filter { it.address.size == 4 } .filter { !it.isLoopbackAddress } .filter { it.address[0] != 10.toByte() } .map { it.hostAddress } }.first() }
Java
The Java code’s a lot more convoluted, and isn’t helped at all by the requirement for a means by which to convert an Enumeration
to a Stream
(copied shamelessly from “Iterate an Enumeration in Java 8“, by the way.) However, it’s functionally equivalent to the Kotlin code. If it can’t find a valid address or an internal exception is thrown, a RuntimeException
is created and thrown.
private staticStream enumerationAsStream(Enumeration e) { return StreamSupport.stream( Spliterators.spliteratorUnknownSize( new Iterator () { public T next() { return e.nextElement(); } public boolean hasNext() { return e.hasMoreElements(); } }, Spliterator.ORDERED), false); } public static String getAddress() { try { Optional address = enumerationAsStream(NetworkInterface.getNetworkInterfaces()) .flatMap(networkInterface -> networkInterface.getInterfaceAddresses().stream() ) .filter(ia -> !ia.getAddress().isLoopbackAddress()) .map(InterfaceAddress::getAddress) .filter(a -> a.getAddress().length == 4) .filter(a -> a.getAddress()[0] != 10) .findFirst(); if (address.isPresent()) { return address.get().getHostAddress(); } else { throw new RuntimeException("Address not accessible"); } } catch (SocketException e) { throw new RuntimeException(e); } }
Summary
This is not perfect code, I wouldn’t think. It was thrown together to fit a specific need, and ideally should have been easily located on StackOverflow or something like that.