UdpChannel. Java SE 7+/Android 8+ UDP client and server, MIT (c) 2025 miktim@mail.ru
Based on Java's DatagramChannel class, which supports source-specific multicast
Notes:
- The UDP protocol does not guarantee datagram delivery, ordering, or duplicate protection.
- The maximum safe UDP payload size is ~508 bytes.
- Don't forget to open the required UDP port in your firewall.
The jar ./dist/udpchannel-... file was generated with debugging info using JDK1.8 for target JRE1.7
package org.miktim.udpchannel;
Overview:
Class UdpChannel implements Closeable, AutoCloseable;
Constants:
static final String VERSION = "2.1.0";
Further in the text: "remote address", "remote port", "remote socket" means "remote" parameter of the constructor.
Constructors:
Creates an unbinded channel with reuse enabled, broadcast on, loopback disabled and one hop.
UdpChannel(String mode, InetSocketAddress remoteSoc, NetworkInterface intf) throws IOException;
UdpChannel(String mode, InetSocketAddress remoteSoc, String intfName) throws IOException;
- the mode is one of the:
"AUTO" : autodetection by remote address type (ipv4/ipv6)
"DEFAULT" : system default
"INET" : StandardProtocolFamily.INET
"INET6" : StandardProtocolFamily.INET6
"UNIX" : StandardProtocolFamily.UNIX (Android)
UdpChannel(InetSocketAddress remoteSoc, NetworkInterface intf) throws IOException;
UdpChannel(InetSocketAddress remoteSoc, String intfName) throws IOException;
- autodetection of the protocol family of the created channel by the type of the remote address (ipv4/ipv6).
Methods:
static boolean isAvailable(int port);
- checks whether the port is available.
static boolean seemsBroadcast(InetAddress addr);
- returns true if ipv4 address ends in .255
DatagramChannel getChannel();
String getMode();
- returns channel creation mode
DatagramSocket getSocket();
InetSocketAddress getRemote();
InetSocketAddress getLocal();
- returns socket address with interfaceAddr/remotePort;
- selected interface address (ipv4/ipv6) depends on remote address
boolean isOpen();
boolean isMulticast();
- returns true if the remote address is multicast
boolean isBound();
UdpChannel bind() throws IOException;
- an unbound channel binds to the remotePort;
UdpChannel bind(InetSocketAddress soc) throws IOException;
- binds channel to the specified socket
boolean isConnected();
UdpChannel connect() throws IOException;
- connects to remote socket
UdpChannel disconnect() throws IOException;
UdpChannel setReuseAddress(boolean enable) throws SocketException;
- enable/disable reuse of net channel
boolean getReuseAddress();
- enabled by default
UdpChannel setBroadcast(boolean on) throws IOException;
boolean getBroadcast() throws IOException;
- returns true if the channel is broadcast
UdpChannel setReceiveBufferSize(int size) throws IOException;
int getReceiveBufferSize() throws IOException;
UdpChannel setSendBufferSize(int size) throws IOException;
int getSendBufferSize() throws IOException;
UdpChannel setLoopbackMode(boolean disable) throws IOException;
- false enables loopback
boolean getLoopbackMode() throws SocketException;
UdpChannel setTimeToLive(int ttl) throws IOException;
int getTimeToLive() throws IOException;
NetworkInterface getNetworkInterface();
UdpChannel setNetworkInterface(NetworkInterface intf);
MembershipKey joinGroup() throws IOException;
- joins to the remote address group via the network interface;
MembershipKey joinGroup(InetAddress source) throws IOException;
- joins to the remote address group via the network interface;
- the resulting membership key is source-specific.
All send/receive methods binds unbouded channel to the remote port (0.0.0.0/remotePort);
int send(byte[] buf) throws IOException;
- sends datagram to remote address/port
- returns the number of bytes sent
int send(byte[] buf, SocketAddress target) throws IOException;
- sends datagram to specified target socket
- returns the number of bytes sent
void send(DatagramPacket dp) throws IOException;
- sends datagram packet to its own address/port or,
if the packet address is null, to the remote address/port
boolean isReceiving();
- returns true if the channel receives datagrams
UdpChannel setPayloadSize(int size);
- sets the payload buffer length for receiving packets
int getPayloadSize();
- default: 1500 bytes
void receive(UdpSocket.Handler handler) throws IOException;
- calls handler.onStart, starts receiving datagrams
void close();
- [stops receiving, calls handler.onClose,] close channel
Interface UdpChannel.Handler
void onStart(UdpChannel uc);
void onError(UdpChannel uc, Exception e);
void onClose(UdpChannel uc);
- called BEFORE closing the socket
void onPacket(UdpChannel uc, DatagramPacket dp);
}
@Override
String toString();
- returns a string with channel info of the form:
"INET UdpChannel remote: MCG /224.0.1.191:9099 bound to: /0.0.0.0:9099
Options:
SO_SNDBUF: 106496 SO_RCVBUF: 106496 SO_REUSEADDR: false SO_BROADCAST: false
IP_TOS: 0 IP_MULTICAST_IF: eth1 IP_MULTICAST_TTL: 1 IP_MULTICAST_LOOP: false"
Helpful Links:
- DatagramChannel:
https://docs.oracle.com/javase/8/docs/api/java/nio/channels/DatagramChannel.html
https://docs.oracle.com/javase/8/docs/api/java/nio/channels/MulticastChannel.html
- IANA address and port registry:
https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml
https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
- Android Multicast Troubleshooting:
https://stackoverflow.com/questions/13221736/android-device-not-receiving-multicast-package
https://stackoverflow.com/questions/27917605/android-multicastsocket-joingroup-doesnt-trigger-sending-igmp-message