Example usage for io.netty.channel.local LocalAddress LocalAddress

List of usage examples for io.netty.channel.local LocalAddress LocalAddress

Introduction

In this page you can find the example usage for io.netty.channel.local LocalAddress LocalAddress.

Prototype

public LocalAddress(String id) 

Source Link

Document

Creates a new instance with the specified ID.

Usage

From source file:com.flysoloing.learning.network.netty.localecho.LocalEcho.java

License:Apache License

public static void main(String[] args) throws Exception {
    // Address to bind on / connect to.
    final LocalAddress addr = new LocalAddress(PORT);

    EventLoopGroup serverGroup = new DefaultEventLoopGroup();
    EventLoopGroup clientGroup = new NioEventLoopGroup(); // NIO event loops are also OK
    try {/*w ww . j  a  v  a  2 s.  co  m*/
        // Note that we can use any event loop to ensure certain local channels
        // are handled by the same event loop thread which drives a certain socket channel
        // to reduce the communication latency between socket channels and local channels.
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(serverGroup).channel(LocalServerChannel.class)
                .handler(new ChannelInitializer<LocalServerChannel>() {
                    @Override
                    public void initChannel(LocalServerChannel ch) throws Exception {
                        ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
                    }
                }).childHandler(new ChannelInitializer<LocalChannel>() {
                    @Override
                    public void initChannel(LocalChannel ch) throws Exception {
                        ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO), new LocalEchoServerHandler());
                    }
                });

        Bootstrap cb = new Bootstrap();
        cb.group(clientGroup).channel(LocalChannel.class).handler(new ChannelInitializer<LocalChannel>() {
            @Override
            public void initChannel(LocalChannel ch) throws Exception {
                ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO), new LocalEchoClientHandler());
            }
        });

        // Start the server.
        sb.bind(addr).sync();

        // Start the client.
        Channel ch = cb.connect(addr).sync().channel();

        // Read commands from the stdin.
        System.out.println("Enter text (quit to end)");
        ChannelFuture lastWriteFuture = null;
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        for (;;) {
            String line = in.readLine();
            if (line == null || "quit".equalsIgnoreCase(line)) {
                break;
            }

            // Sends the received line to the server.
            lastWriteFuture = ch.writeAndFlush(line);
        }

        // Wait until all messages are flushed before closing the channel.
        if (lastWriteFuture != null) {
            lastWriteFuture.awaitUninterruptibly();
        }
    } finally {
        serverGroup.shutdownGracefully();
        clientGroup.shutdownGracefully();
    }
}

From source file:com.google.cloud.logging.spi.v2.testing.LocalLoggingHelper.java

License:Open Source License

/**
 * Constructs a new LocalPubsubHelper. The method start() must
 * be called before it is used./*from   ww w . j av a 2  s  .co m*/
 */
public LocalLoggingHelper(String addressString) {
    address = new LocalAddress(addressString);
    loggingImpl = new LocalLoggingImpl();
    NettyServerBuilder builder = NettyServerBuilder.forAddress(address).flowControlWindow(FLOW_CONTROL_WINDOW)
            .channelType(LocalServerChannel.class);
    builder.addService(LoggingServiceV2Grpc.bindService(loggingImpl));
    server = builder.build();
}

From source file:com.google.cloud.logging.v2.testing.LocalLoggingHelper.java

License:Apache License

/**
 * Constructs a new LocalLoggingHelper. The method start() must
 * be called before it is used.//from w  w w .ja v a 2  s  .c o  m
 */
public LocalLoggingHelper(String addressString) {
    address = new LocalAddress(addressString);
    loggingImpl = new LocalLoggingImpl();
    NettyServerBuilder builder = NettyServerBuilder.forAddress(address).flowControlWindow(FLOW_CONTROL_WINDOW)
            .channelType(LocalServerChannel.class);
    builder.addService(loggingImpl.bindService());
    server = builder.build();
}

From source file:com.hxr.javatone.concurrency.netty.official.localecho.LocalEcho.java

License:Apache License

public void run() throws Exception {
    // Address to bind on / connect to.
    final LocalAddress addr = new LocalAddress(port);

    EventLoopGroup serverGroup = new DefaultEventLoopGroup();
    EventLoopGroup clientGroup = new NioEventLoopGroup(); // NIO event loops are also OK
    try {//from  w w  w  . jav a  2 s . c  om
        // Note that we can use any event loop to ensure certain local channels
        // are handled by the same event loop thread which drives a certain socket channel
        // to reduce the communication latency between socket channels and local channels.
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(serverGroup).channel(LocalServerChannel.class)
                .handler(new ChannelInitializer<LocalServerChannel>() {
                    @Override
                    public void initChannel(LocalServerChannel ch) throws Exception {
                        ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
                    }
                }).childHandler(new ChannelInitializer<LocalChannel>() {
                    @Override
                    public void initChannel(LocalChannel ch) throws Exception {
                        ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO), new LocalEchoServerHandler());
                    }
                });

        Bootstrap cb = new Bootstrap();
        cb.group(clientGroup).channel(LocalChannel.class).handler(new ChannelInitializer<LocalChannel>() {
            @Override
            public void initChannel(LocalChannel ch) throws Exception {
                ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO), new LocalEchoClientHandler());
            }
        });

        // Start the server.
        sb.bind(addr).sync();

        // Start the client.
        Channel ch = cb.connect(addr).sync().channel();

        // Read commands from the stdin.
        System.out.println("Enter text (quit to end)");
        ChannelFuture lastWriteFuture = null;
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        for (;;) {
            String line = in.readLine();
            if (line == null || "quit".equalsIgnoreCase(line)) {
                break;
            }

            // Sends the received line to the server.
            lastWriteFuture = ch.writeAndFlush(line);
        }

        // Wait until all messages are flushed before closing the channel.
        if (lastWriteFuture != null) {
            lastWriteFuture.awaitUninterruptibly();
        }
    } finally {
        serverGroup.shutdownGracefully();
        clientGroup.shutdownGracefully();
    }
}

From source file:com.lambdaworks.redis.ConnectionEventTrigger.java

License:Apache License

static SocketAddress remote(ChannelHandlerContext ctx) {
    if (ctx.channel() != null && ctx.channel().remoteAddress() != null) {
        return ctx.channel().remoteAddress();
    }/*from w  ww  .  j  av  a  2 s.  co m*/
    return new LocalAddress("unknown");
}

From source file:com.lambdaworks.redis.metrics.CommandLatencyIdTest.java

License:Apache License

@Test
public void testValues() throws Exception {
    assertThat(sut.localAddress()).isEqualTo(LocalAddress.ANY);
    assertThat(sut.remoteAddress()).isEqualTo(new LocalAddress("me"));
}

From source file:com.springapp.mvc.netty.example.localecho.LocalEcho.java

License:Apache License

public static void main(String[] args) throws Exception {
    // Address to bind on / connect to.
    final LocalAddress addr = new LocalAddress(PORT);

    EventLoopGroup serverGroup = new LocalEventLoopGroup();
    EventLoopGroup clientGroup = new NioEventLoopGroup(); // NIO event loops are also OK
    try {//from   ww w . j  a v a2 s .c  om
        // Note that we can use any event loop to ensure certain local channels
        // are handled by the same event loop thread which drives a certain socket channel
        // to reduce the communication latency between socket channels and local channels.
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(serverGroup).channel(LocalServerChannel.class)
                .handler(new ChannelInitializer<LocalServerChannel>() {
                    @Override
                    public void initChannel(LocalServerChannel ch) throws Exception {
                        ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
                    }
                }).childHandler(new ChannelInitializer<LocalChannel>() {
                    @Override
                    public void initChannel(LocalChannel ch) throws Exception {
                        ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO), new LocalEchoServerHandler());
                    }
                });

        Bootstrap cb = new Bootstrap();
        cb.group(clientGroup).channel(LocalChannel.class).handler(new ChannelInitializer<LocalChannel>() {
            @Override
            public void initChannel(LocalChannel ch) throws Exception {
                ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO), new LocalEchoClientHandler());
            }
        });

        // Start the server.
        sb.bind(addr).sync();

        // Start the client.
        Channel ch = cb.connect(addr).sync().channel();

        // Read commands from the stdin.
        System.out.println("Enter text (quit to end)");
        ChannelFuture lastWriteFuture = null;
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        for (;;) {
            String line = in.readLine();
            if (line == null || "quit".equalsIgnoreCase(line)) {
                break;
            }

            // Sends the received line to the server.
            lastWriteFuture = ch.writeAndFlush(line);
        }

        // Wait until all messages are flushed before closing the channel.
        if (lastWriteFuture != null) {
            lastWriteFuture.awaitUninterruptibly();
        }
    } finally {
        serverGroup.shutdownGracefully();
        clientGroup.shutdownGracefully();
    }
}

From source file:com.twitter.http2.HttpHeaderCompressionTest.java

License:Apache License

private void testHeaderEcho(HttpHeaderBlockFrame frame) throws Throwable {
    final EchoHandler sh = new EchoHandler();
    final TestHandler ch = new TestHandler(frame);

    ServerBootstrap sb = new ServerBootstrap().group(new LocalEventLoopGroup())
            .channel(LocalServerChannel.class).childHandler(new ChannelInitializer<LocalChannel>() {
                @Override//from   w  w w. j a  va2 s  .co m
                public void initChannel(LocalChannel channel) throws Exception {
                    channel.pipeline().addLast(new HttpConnectionHandler(true), sh);
                }
            });
    Bootstrap cb = new Bootstrap().group(new LocalEventLoopGroup()).channel(LocalChannel.class)
            .handler(new ChannelInitializer<LocalChannel>() {
                @Override
                public void initChannel(LocalChannel channel) throws Exception {
                    channel.pipeline().addLast(new HttpConnectionHandler(false), ch);
                }
            });

    LocalAddress localAddress = new LocalAddress("HttpHeaderCompressionTest");
    Channel sc = sb.bind(localAddress).sync().channel();
    ChannelFuture ccf = cb.connect(localAddress);
    assertTrue(ccf.awaitUninterruptibly().isSuccess());

    while (!ch.success) {
        if (sh.exception.get() != null) {
            break;
        }
        if (ch.exception.get() != null) {
            break;
        }

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            // Ignore.
        }
    }

    sc.close().awaitUninterruptibly();
    cb.group().shutdownGracefully();
    sb.group().shutdownGracefully();

    if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) {
        throw sh.exception.get();
    }
    if (ch.exception.get() != null && !(ch.exception.get() instanceof IOException)) {
        throw ch.exception.get();
    }
    if (sh.exception.get() != null) {
        throw sh.exception.get();
    }
    if (ch.exception.get() != null) {
        throw ch.exception.get();
    }
}

From source file:dorkbox.network.Client.java

License:Apache License

/**
 * Starts a REMOTE <b>only</b> client, which will connect to the specified host using the specified Connections Options
 *//*  w w w  .  j a  v a  2  s .com*/
@SuppressWarnings("AutoBoxing")
public Client(final Configuration config) throws SecurityException {
    super(config);

    String threadName = Client.class.getSimpleName();

    this.config = config;
    boolean hostConfigured = (config.tcpPort > 0 || config.udpPort > 0) && config.host != null;
    boolean isLocalChannel = config.localChannelName != null;

    if (isLocalChannel && hostConfigured) {
        String msg = threadName
                + " Local channel use and TCP/UDP use are MUTUALLY exclusive. Unable to determine what to do.";
        logger.error(msg);
        throw new IllegalArgumentException(msg);
    }

    localChannelName = config.localChannelName;
    hostName = config.host;

    Bootstrap localBootstrap = null;
    Bootstrap tcpBootstrap = null;
    Bootstrap udpBootstrap = null;

    if (config.localChannelName != null) {
        localBootstrap = new Bootstrap();
    }

    if (config.tcpPort > 0 || config.udpPort > 0) {
        if (config.host == null) {
            throw new IllegalArgumentException("You must define what host you want to connect to.");
        }

        if (config.host.equals("0.0.0.0")) {
            throw new IllegalArgumentException(
                    "You cannot connect to 0.0.0.0, you must define what host you want to connect to.");
        }
    }

    if (config.tcpPort > 0) {
        tcpBootstrap = new Bootstrap();
    }

    if (config.udpPort > 0) {
        udpBootstrap = new Bootstrap();
    }

    if (localBootstrap == null && tcpBootstrap == null && udpBootstrap == null) {
        throw new IllegalArgumentException(
                "You must define how you want to connect, either LOCAL channel name, TCP port, or UDP port");
    }

    if (config.localChannelName != null) {
        // no networked bootstraps. LOCAL connection only

        bootstraps.add(new BootstrapWrapper("LOCAL", config.localChannelName, -1, localBootstrap));

        localBootstrap.group(newEventLoop(LOCAL, 1, threadName + "-JVM-BOSS")).channel(LocalChannel.class)
                .remoteAddress(new LocalAddress(config.localChannelName))
                .handler(new RegistrationLocalHandlerClient(threadName, registrationWrapper));
    }

    EventLoopGroup workerEventLoop = null;
    if (tcpBootstrap != null || udpBootstrap != null) {
        workerEventLoop = newEventLoop(config.workerThreadPoolSize, threadName);
    }

    if (tcpBootstrap != null) {
        bootstraps.add(new BootstrapWrapper("TCP", config.host, config.tcpPort, tcpBootstrap));

        if (OS.isAndroid()) {
            // android ONLY supports OIO (not NIO)
            tcpBootstrap.channel(OioSocketChannel.class);
        } else if (OS.isLinux() && NativeLibrary.isAvailable()) {
            // epoll network stack is MUCH faster (but only on linux)
            tcpBootstrap.channel(EpollSocketChannel.class);
        } else if (OS.isMacOsX() && NativeLibrary.isAvailable()) {
            // KQueue network stack is MUCH faster (but only on macosx)
            tcpBootstrap.channel(KQueueSocketChannel.class);
        } else {
            tcpBootstrap.channel(NioSocketChannel.class);
        }

        tcpBootstrap.group(newEventLoop(1, threadName + "-TCP-BOSS"))
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
                .remoteAddress(config.host, config.tcpPort).handler(new RegistrationRemoteHandlerClientTCP(
                        threadName, registrationWrapper, workerEventLoop));

        // android screws up on this!!
        tcpBootstrap.option(ChannelOption.TCP_NODELAY, !OS.isAndroid()).option(ChannelOption.SO_KEEPALIVE,
                true);
    }

    if (udpBootstrap != null) {
        bootstraps.add(new BootstrapWrapper("UDP", config.host, config.udpPort, udpBootstrap));

        if (OS.isAndroid()) {
            // android ONLY supports OIO (not NIO)
            udpBootstrap.channel(OioDatagramChannel.class);
        } else if (OS.isLinux() && NativeLibrary.isAvailable()) {
            // epoll network stack is MUCH faster (but only on linux)
            udpBootstrap.channel(EpollDatagramChannel.class);
        } else if (OS.isMacOsX() && NativeLibrary.isAvailable()) {
            // KQueue network stack is MUCH faster (but only on macosx)
            udpBootstrap.channel(KQueueDatagramChannel.class);
        } else {
            udpBootstrap.channel(NioDatagramChannel.class);
        }

        udpBootstrap.group(newEventLoop(1, threadName + "-UDP-BOSS"))
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                // Netty4 has a default of 2048 bytes as upper limit for datagram packets.
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(EndPoint.udpMaxSize))
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
                .localAddress(new InetSocketAddress(0)) // bind to wildcard
                .remoteAddress(new InetSocketAddress(config.host, config.udpPort))
                .handler(new RegistrationRemoteHandlerClientUDP(threadName, registrationWrapper,
                        workerEventLoop));

        // Enable to READ and WRITE MULTICAST data (ie, 192.168.1.0)
        // in order to WRITE: write as normal, just make sure it ends in .255
        // in order to LISTEN:
        //    InetAddress group = InetAddress.getByName("203.0.113.0");
        //    NioDatagramChannel.joinGroup(group);
        // THEN once done
        //    NioDatagramChannel.leaveGroup(group), close the socket
        udpBootstrap.option(ChannelOption.SO_BROADCAST, false).option(ChannelOption.SO_SNDBUF, udpMaxSize);
    }
}

From source file:dorkbox.network.Server.java

License:Apache License

/**
 * Convenience method to starts a server with the specified Connection Options
 *///from   w ww  .  ja v  a 2s . c o  m
@SuppressWarnings("AutoBoxing")
public Server(Configuration config) throws SecurityException {
    // watch-out for serialization... it can be NULL incoming. The EndPoint (superclass) sets it, if null, so
    // you have to make sure to use this.serialization
    super(config);

    tcpPort = config.tcpPort;
    udpPort = config.udpPort;

    localChannelName = config.localChannelName;

    if (config.host == null) {
        // we set this to "0.0.0.0" so that it is clear that we are trying to bind to that address.
        hostName = "0.0.0.0";

        // make it clear that this is what we do (configuration wise) so that variable examination is consistent
        config.host = hostName;
    } else {
        hostName = config.host;
    }

    if (localChannelName != null) {
        localBootstrap = new ServerBootstrap();
    } else {
        localBootstrap = null;
    }

    if (tcpPort > 0) {
        tcpBootstrap = new ServerBootstrap();
    } else {
        tcpBootstrap = null;
    }

    if (udpPort > 0) {
        // This is what allows us to have UDP behave "similar" to TCP, in that a session is established based on the port/ip of the
        // remote connection. This allows us to reuse channels and have "state" for a UDP connection that normally wouldn't exist.
        // Additionally, this is what responds to discovery broadcast packets
        udpBootstrap = new SessionBootstrap(tcpPort, udpPort);
    } else {
        udpBootstrap = null;
    }

    String threadName = Server.class.getSimpleName();

    // always use local channels on the server.
    if (localBootstrap != null) {
        localBootstrap
                .group(newEventLoop(LOCAL, 1, threadName + "-JVM-BOSS"), newEventLoop(LOCAL, 1, threadName))
                .channel(LocalServerChannel.class)
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
                .localAddress(new LocalAddress(localChannelName))
                .childHandler(new RegistrationLocalHandlerServer(threadName, registrationWrapper));
    }

    EventLoopGroup workerEventLoop = null;
    if (tcpBootstrap != null || udpBootstrap != null) {
        workerEventLoop = newEventLoop(config.workerThreadPoolSize, threadName);
    }

    if (tcpBootstrap != null) {
        if (OS.isAndroid()) {
            // android ONLY supports OIO (not NIO)
            tcpBootstrap.channel(OioServerSocketChannel.class);
        } else if (OS.isLinux() && NativeLibrary.isAvailable()) {
            // epoll network stack is MUCH faster (but only on linux)
            tcpBootstrap.channel(EpollServerSocketChannel.class);
        } else if (OS.isMacOsX() && NativeLibrary.isAvailable()) {
            // KQueue network stack is MUCH faster (but only on macosx)
            tcpBootstrap.channel(KQueueServerSocketChannel.class);
        } else {
            tcpBootstrap.channel(NioServerSocketChannel.class);
        }

        // TODO: If we use netty for an HTTP server,
        // Beside the usual ChannelOptions the Native Transport allows to enable TCP_CORK which may come in handy if you implement a HTTP Server.

        tcpBootstrap
                .group(newEventLoop(1, threadName + "-TCP-BOSS"),
                        newEventLoop(1, threadName + "-TCP-REGISTRATION"))
                .option(ChannelOption.SO_BACKLOG, backlogConnectionCount)
                .option(ChannelOption.SO_REUSEADDR, true)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))

                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new RegistrationRemoteHandlerServerTCP(threadName, registrationWrapper,
                        workerEventLoop));

        // have to check options.host for "0.0.0.0". we don't bind to "0.0.0.0", we bind to "null" to get the "any" address!
        if (hostName.equals("0.0.0.0")) {
            tcpBootstrap.localAddress(tcpPort);
        } else {
            tcpBootstrap.localAddress(hostName, tcpPort);
        }

        // android screws up on this!!
        tcpBootstrap.option(ChannelOption.TCP_NODELAY, !OS.isAndroid()).childOption(ChannelOption.TCP_NODELAY,
                !OS.isAndroid());
    }

    if (udpBootstrap != null) {
        if (OS.isAndroid()) {
            // android ONLY supports OIO (not NIO)
            udpBootstrap.channel(OioDatagramChannel.class);
        } else if (OS.isLinux() && NativeLibrary.isAvailable()) {
            // epoll network stack is MUCH faster (but only on linux)
            udpBootstrap.channel(EpollDatagramChannel.class);
        } else if (OS.isMacOsX() && NativeLibrary.isAvailable()) {
            // KQueue network stack is MUCH faster (but only on macosx)
            udpBootstrap.channel(KQueueDatagramChannel.class);
        } else {
            // windows and linux/mac that are incompatible with the native implementations
            udpBootstrap.channel(NioDatagramChannel.class);
        }

        // Netty4 has a default of 2048 bytes as upper limit for datagram packets, we want this to be whatever we specify
        FixedRecvByteBufAllocator recvByteBufAllocator = new FixedRecvByteBufAllocator(EndPoint.udpMaxSize);

        udpBootstrap
                .group(newEventLoop(1, threadName + "-UDP-BOSS"),
                        newEventLoop(1, threadName + "-UDP-REGISTRATION"))
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .option(ChannelOption.RCVBUF_ALLOCATOR, recvByteBufAllocator)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))

                // a non-root user can't receive a broadcast packet on *nix if the socket is bound on non-wildcard address.
                // TODO: move broadcast to it's own handler, and have UDP server be able to be bound to a specific IP
                // OF NOTE: At the end in my case I decided to bind to .255 broadcast address on Linux systems. (to receive broadcast packets)
                .localAddress(udpPort) // if you bind to a specific interface, Linux will be unable to receive broadcast packets! see: http://developerweb.net/viewtopic.php?id=5722
                .childHandler(new RegistrationRemoteHandlerServerUDP(threadName, registrationWrapper,
                        workerEventLoop));

        // // have to check options.host for null. we don't bind to 0.0.0.0, we bind to "null" to get the "any" address!
        // if (hostName.equals("0.0.0.0")) {
        //     udpBootstrap.localAddress(hostName, tcpPort);
        // }
        // else {
        //     udpBootstrap.localAddress(udpPort);
        // }

        // Enable to READ from MULTICAST data (ie, 192.168.1.0)
        // in order to WRITE: write as normal, just make sure it ends in .255
        // in order to LISTEN:
        //    InetAddress group = InetAddress.getByName("203.0.113.0");
        //    socket.joinGroup(group);
        // THEN once done
        //    socket.leaveGroup(group), close the socket
        // Enable to WRITE to MULTICAST data (ie, 192.168.1.0)
        udpBootstrap.option(ChannelOption.SO_BROADCAST, false).option(ChannelOption.SO_SNDBUF, udpMaxSize);
    }
}