Netty UDP 客户端发消息后接收服务器信息

在本站大神的文章的基础上,加入了我的项目需求,当客户端用UDP给服务端发送消息后,接收到服务端返回的消息再关闭客户端。

UdpServer.java
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;

/**
 * UDP Server
 *
 * @author sxp
 *
 */
public class UdpServer {

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioDatagramChannel.class).option(ChannelOption.SO_BROADCAST, true)
                    .handler(new UdpServerHandler());
            b.bind(8080).sync().channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}
UdpServerHandler.java
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.ThreadLocalRandom;

/**
 * UDP Server Handler Class
 *
 * @author sxp
 *
 */
public class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    private static final String[] proverbs = { "只要功夫深,铁棒磨成针。", "旧时王谢堂前燕,飞入寻常百姓家。", "洛阳亲友如相问,一片冰心在玉壶。",
            "一寸光阴一寸金,寸金难买寸光阴。", "老骥伏枥,志在千里。烈士暮年,壮心不已!" };
    private static final String[] idioms = { "马到成功", "狐假虎威", "虎头虎脑", "生龙活虎", "如雷贯耳", "持之以恒" };

    /**
     * 随机返回谚语
     */
    private String nextProverb() {
        int nextInt = ThreadLocalRandom.current().nextInt(proverbs.length);
        return proverbs[nextInt];
    }

    /**
     * 随机返回成语
     */
    private String nextIdiom() {
        int nextInt = ThreadLocalRandom.current().nextInt(idioms.length);
        return idioms[nextInt];
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
        String message = msg.content().toString(CharsetUtil.UTF_8);
        System.out.println("服务端从" + msg.sender() + "接收到的消息:" + message);
        String sendMessage;
        if ("谚语".equals(message)) {
            sendMessage = nextProverb();
        } else if ("成语".equals(message)) {
            sendMessage = nextIdiom();
            ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(sendMessage, CharsetUtil.UTF_8), msg.sender()));
        }
        else if ("成语9".equals(message)) {
            sendMessage = "可以停了";
            ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(sendMessage, CharsetUtil.UTF_8), msg.sender()));
            return;
        }else {
            sendMessage = "请发送:“谚语”或者“成语”";
            ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(sendMessage, CharsetUtil.UTF_8), msg.sender()));
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

}

UdpClient.java
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.CharsetUtil;

import java.net.InetSocketAddress;

/**
 * UDP Client
 *
 * @author sxp
 *
 */
public class UdpClient {

    public static Channel channel;

    public static EventLoopGroup group;

    public static void main(String[] args) throws InterruptedException {
        group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioDatagramChannel.class).option(ChannelOption.SO_BROADCAST, true)
                    .remoteAddress("127.0.0.1", 8080)
                    .handler(new UdpClientHandler());
            channel = b.bind(8082).sync().channel();
            for (int i = 1; i < 10; i++) {
                String text = "成语";
                if(i == 9) {
                    text = "成语9";
                }
                channel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer( text, CharsetUtil.UTF_8),
                        new InetSocketAddress("127.0.0.1", 8080)));
            }
//            channel.close();
        } finally {
//            group.shutdownGracefully();
        }
    }

    public Channel getChannel(){
        return channel;
    }

    public EventLoopGroup getGroup(){
        return group;
    }


}

UdpClientHandler.java
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;

/**
 * UDP Client Handler Class
 *
 * @author sxp
 *
 */
public class UdpClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
        String receiveMessage = msg.content().toString(CharsetUtil.UTF_8);
        System.out.println(receiveMessage);
        if(receiveMessage.equals("可以停了")) {
            UdpClient udpClient = new UdpClient();
            Channel channel = udpClient.getChannel();
            channel.close();
            EventLoopGroup group = udpClient.getGroup();
            group.shutdownGracefully();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

}


 依次启动UdpServer.java和UdpClient.java中的main方法后,执行结果为:

可以发现,客户端是在执行完任务并接收到服务器返回的消息后才关闭的。 

啦啦啦啦啦啦。一起冲冲冲。

### 回答1: Netty是一个基于Java的网络编程框架,它支持多种协议和传输方式,包括UDP。要创建一个NettyUDP客户端,需要以下步骤: 1. 创建一个Bootstrap对象,用于配置和启动Netty客户端。 2. 设置客户端的Channel类型为NioDatagramChannel,这是UDP协议的通道类型。 3. 设置客户端的处理器,用于处理接收到的消息和发送消息。 4. 连接到UDP服务器,可以使用Bootstrap的connect()方法或者bind()方法来指定服务器的地址和端口号。 5. 发送消息到服务器,可以使用客户端的Channel对象来发送数据。 下面是一个简单的Netty UDP客户端的示例代码: ``` EventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioDatagramChannel.class) .handler(new SimpleChannelInboundHandler<DatagramPacket>() { @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { // 处理接收到的消息 } }); Channel channel = bootstrap.bind(0).sync().channel(); InetSocketAddress serverAddress = new InetSocketAddress("localhost", 12345); channel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("Hello", CharsetUtil.UTF_8), serverAddress)); ``` 在这个示例代码中,我们创建了一个NioEventLoopGroup对象作为事件循环组,创建了一个Bootstrap对象,并设置了客户端的通道类型为NioDatagramChannel,设置了客户端的处理器为一个SimpleChannelInboundHandler对象。然后,我们绑定了客户端的端口号为0,表示由系统自动分配一个未使用的端口号。最后,我们创建了一个InetSocketAddress对象,指定了服务器的地址和端口号,并使用客户端的Channel对象发送了一条消息到服务器。 ### 回答2: netty是一个高性能的网络编程框架,可以用于构建各种类型的网络应用程序,包括UDP(User Datagram Protocol)客户端。 在使用netty构建UDP客户端时,需要按照以下步骤进行操作。 首先,需要创建一个Bootstrap实例,用于配置和启动netty客户端。可以通过如下代码创建Bootstrap实例: ``` Bootstrap bootstrap = new Bootstrap(); ``` 接下来,需要配置Bootstrap实例。配置包括指定EventLoopGroup用于处理客户端的I/O操作,设置通道类型为NioDatagramChannel(用于UDP协议),设置远程服务器的地址和端口等。 ``` bootstrap.group(new NioEventLoopGroup()) .channel(NioDatagramChannel.class) .remoteAddress(new InetSocketAddress("服务器地址", 服务器端口)) .handler(new ChannelInitializer<DatagramChannel>() { @Override protected void initChannel(DatagramChannel channel) throws Exception { ChannelPipeline pipeline = channel.pipeline(); // 添加自定义的处理器 pipeline.addLast(new MyHandler()); } }); ``` 然后,需要自定义一个处理器类(MyHandler),用于处理接收发送的数据。在该类中,可以重写channelRead方法用于处理接收到的数据,也可以重写channelActive方法用于在连接建立时发送数据。 ``` public class MyHandler extends SimpleChannelInboundHandler<DatagramPacket> { @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception { ByteBuf buf = packet.content(); // 处理接收到的数据 } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { // 发送数据 ByteBuf buf = ctx.alloc().buffer(); // 将数据写入buf DatagramPacket packet = new DatagramPacket(buf, remoteAddress); ctx.writeAndFlush(packet); } } ``` 最后,调用bootstrap的bind方法启动客户端,并通过调用ChannelFuture的sync方法阻塞线程直到连接完成。 ``` ChannelFuture future = bootstrap.bind().sync(); ``` 以上就是使用netty构建UDP客户端的简单流程。通过创建Bootstrap实例、配置与远程服务器的连接、自定义处理器类以及启动客户端,就可以实现netty UDP客户端的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值