Open fuzhengwei opened 1 year ago
定义消息应答服务处理类,改类主要随机从字符串数组中选择一个发送给客户端
public class AnswerHandler extends SimpleChannelInboundHandler<DatagramPacket> { /*应答的具体内容从常量字符串数组中取得,由nextQuote方法随机获取*/ private static final String[] DICTIONARY = { "测试消息"}; private static Random r = new Random(); private String nextQuote(){ return DICTIONARY[r.nextInt(DICTIONARY.length-1)]; } @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception { //获得请求 String req = packet.content().toString(CharsetUtil.UTF_8); System.out.println("接收到请求:"+req); if(UdpQuestionSide.QUESTION.equals(req)){ String answer = UdpAnswerSide.ANSWER+nextQuote(); System.out.println("接收到请求:"+req); /** * 重新 new 一个DatagramPacket对象,我们通过packet.sender()来获取发送者的消息。重新发送出去! */ ctx.writeAndFlush( new DatagramPacket( Unpooled.copiedBuffer( answer, CharsetUtil.UTF_8), packet.sender())); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); cause.printStackTrace(); } }
定义应答服务器
public final static String ANSWER = "笑话来了:"; public void run(int port) throws Exception{ EventLoopGroup group = new NioEventLoopGroup(); try { /*和tcp的不同,udp没有接受连接的说法,所以即使是接收端, 也使用Bootstrap*/ Bootstrap b = new Bootstrap(); /*由于我们用的是UDP协议,所以要用NioDatagramChannel来创建*/ b.group(group) .channel(NioDatagramChannel.class) .handler(new AnswerHandler()); //没有接受客户端连接的过程,监听本地端口即可 ChannelFuture f = b.bind(port).sync(); System.out.println("应答服务已启动....."); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } public static void main(String [] args) throws Exception{ int port = 7397; new UdpAnswerSide().run(port); } 复制代码
3、QuestoinHandler
定义应答服务器处理handler
public class QuestoinHandler extends SimpleChannelInboundHandler<DatagramPacket> { @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { //获得应答,DatagramPacket提供了content()方法取得报文的实际内容 String response = msg.content().toString(CharsetUtil.UTF_8); if (response.startsWith(UdpAnswerSide.ANSWER)) { System.out.println(response); ctx.close(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } } 复制代码
4、UdpQuestionSide
定义了一个请求客户端
public class UdpQuestionSide { public final static String QUESTION = "测试"; public void run(int port) throws Exception{ EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) /*由于我们用的是UDP协议,所以要用NioDatagramChannel来创建*/ .channel(NioDatagramChannel.class) .handler(new QuestoinHandler()); //不需要建立连接 Channel ch = b.bind(0).sync().channel(); //将UDP请求的报文以DatagramPacket打包发送给接受端 ch.writeAndFlush( new DatagramPacket( Unpooled.copiedBuffer(QUESTION, CharsetUtil.UTF_8), new InetSocketAddress("127.0.0.1", port))) .sync(); //不知道接收端能否收到报文,也不知道能否收到接收端的应答报文 // 所以等待15秒后,不再等待,关闭通信 if(!ch.closeFuture().await(15000)){ System.out.println("查询超时!"); } } catch (Exception e) { group.shutdownGracefully(); } } public static void main(String [] args) throws Exception{ int answerPort = 7397; new UdpQuestionSide().run(answerPort); } }
如果发送到多个不同的客户端,如何改进呢?
AnswerHandler
定义消息应答服务处理类,改类主要随机从字符串数组中选择一个发送给客户端
UdpAnswerSide
定义应答服务器
3、QuestoinHandler
定义应答服务器处理handler
4、UdpQuestionSide
定义了一个请求客户端