udp server
java
package com.example.demo.udp;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.FixedRecvByteBufAllocator;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
/**
* A UDP server that responds to the QOTM (quote of the moment) request to a {@link UdpClient}.
* <p>
* Inspired by <a href="https://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html">the official
* Java tutorial</a>.
*/
public final class UdpServer {
private static final int PORT = Integer.parseInt(System.getProperty("port", "7686"));
public static void main(String[] args) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioDatagramChannel.class)
.option(ChannelOption.SO_BROADCAST, true)
// 设置读缓冲区为 10M
.option(ChannelOption.SO_RCVBUF, 1024 * 1024*10)
// 设置写缓冲区为1M
.option(ChannelOption.SO_SNDBUF, 1024 * 1024)
//解决最大接收2048个字节
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
.handler(new UdpServerHandler());
b.bind(PORT).sync().channel().closeFuture().await();
} finally {
group.shutdownGracefully();
}
}
}
handler
java
package com.example.demo.udp;
import com.google.common.collect.Maps;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.AttributeKey;
import io.netty.util.CharsetUtil;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.Objects;
public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
public static Map<String, Channel> channelMap = Maps.newHashMap();
@Override
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
String msg = packet.content().toString(CharsetUtil.UTF_8);
System.err.println("服务端接收消息:" + msg.length());
System.err.println("服务端接收消息:" + msg);
InetSocketAddress inetSocketAddress = packet.sender();
System.out.println("---------" + inetSocketAddress.getHostString());
System.out.println("==========" + inetSocketAddress.getPort());
channelMap.put(inetSocketAddress.getHostString() + ":" + inetSocketAddress.getPort(), ctx.channel());
ctx.channel().attr(AttributeKey.valueOf("deviceId")).setIfAbsent(inetSocketAddress.getHostString() + ":" + inetSocketAddress.getPort());
//向指定客户端发消息
Channel channel = channelMap.get("172.16.50.14:10010");
if (Objects.nonNull(channel) && channel.isActive()) {
InetSocketAddress ii = new InetSocketAddress("172.16.50.14",10010);
channel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("receice---- data", CharsetUtil.UTF_8),ii));
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
// We don't close the channel because we can keep serving requests.
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
//下线
String id = (String) ctx.channel().attr(AttributeKey.valueOf("deviceId")).get();
// map移除channel
channelMap.remove(id);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
//有新的连接
System.out.println(ctx.channel().remoteAddress().toString());
}
}