/UdpServerSocketChannel

Netty udp server socket channel which allocates separate channel per remote address

Primary LanguageJavaGNU Lesser General Public License v3.0LGPL-3.0

UdpServerSocketChannel:

UDP server for netty 4.1 which allocates user channel per remote address (just like netty TCP server)
By default allocated channels are never closed, so it's up to user to close channels upon read timeout or any other event

Can also use multiple threads for IO if running epoll capable system (via SO_REUSEPORT)

Jenkins:

http://build.true-games.org/view/ProtocolSupport/job/UdpServerSocketChannel/

License:

GNU LGPLv3

Usage example:


import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.DefaultEventLoopGroup;
import io.netty.channel.ServerChannel;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import udpserversocketchannel.channel.UdpServerChannel;

public class ExampleUdpServer {

	public static void main(String[] args) {
		ServerBootstrap bootstrap = new ServerBootstrap()
		.group(new DefaultEventLoopGroup())
		.childHandler(new ChannelInitializer<Channel>() {
			@Override
			protected void initChannel(Channel channel) throws Exception {
				channel.pipeline()
				.addLast(new ReadTimeoutHandler(2))
				.addLast(new Echo());
			}
		});
		if (args.length > 0) {
			int ioThreads = Integer.parseInt(args[0]);
			bootstrap.channelFactory(new ChannelFactory<ServerChannel>() {
				@Override
				public ServerChannel newChannel() {
					return new UdpServerChannel(ioThreads);
				}
			});
		} else {
			bootstrap.channel(UdpServerChannel.class);
		}
		bootstrap.bind("0.0.0.0", 1122).syncUninterruptibly();
	}

	private static class Echo extends SimpleChannelInboundHandler<ByteBuf> {
		@Override
		public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {
			ctx.channel().close();
		}
		@Override
		public void channelActive(ChannelHandlerContext ctx) throws Exception {
			super.channelActive(ctx);
			System.err.println("ACTIVE: "+ctx.channel().remoteAddress());
		}
		@Override
		public void channelInactive(ChannelHandlerContext ctx) throws Exception {
			super.channelInactive(ctx);
			System.err.println("INACTIVE: "+ctx.channel().remoteAddress());
		}
		@Override
		protected void channelRead0(ChannelHandlerContext ctx, ByteBuf bytebuf) throws Exception {
			System.err.print("DATA: "+bytebuf.toString(StandardCharsets.UTF_8));
			ctx.channel().writeAndFlush(Unpooled.copiedBuffer(bytebuf));
		}
	}

}```