Netty框架基于UDP实战(一):局域网扫描功能的实现

本文介绍了一个基于Netty的UDP广播实现方案,包括服务端和客户端代码示例。服务端能够接收并响应客户端发送的广播请求,客户端则可以通过广播方式搜索局域网内的服务端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境:
compile 'io.netty:netty-all:4.1.2.Final'


服务端:SearchServer.java

package nettytest.udp;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 局域网扫描发现功能的实现,基于netty的udp
 * Created by Lovell on 9/29/16.
 */
/*
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@  @@@@@@@@        @@  @@@@@@@  @@        @@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@  @@@@@  @@@  @@@@@@@@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@@  @@@  @@@@       @@@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@@@  @  @@@@@  @@@@@@@@  @@@@@@@@@  @@@@@@@@@@
 @@@@        @@        @@@@@@   @@@@@@        @@        @@@        @@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 */

public class SearchServer {
    private static Logger logger = LoggerFactory.getLogger(SearchServer.class);

    /**
     *  udp服务端,接受客户端发送的广播
     */
    public static void initServer() {
        try {
            Bootstrap bootstrap = new Bootstrap();
            EventLoopGroup group = new NioEventLoopGroup();
            bootstrap.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new UdpServerHandler());
            Channel channel = bootstrap.bind(AppConstants.SEARCH_PORT).sync().channel();
            channel.closeFuture().await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
            ByteBuf buf = msg.copy().content();
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            String body = new String(req, "UTF-8");
            logger.info(body);// 打印收到的信息

            // 向客户端发送消息
            String json = "给客户端发送的内容";

            // 由于数据报的数据是以字符数组传的形式存储的,所以传转数据
            byte[] bytes = json.getBytes("UTF-8");
            DatagramPacket data = new DatagramPacket(Unpooled.copiedBuffer(bytes), msg.sender());
            // 向客户端发送消息
            ctx.writeAndFlush(data);
        }
    }

}

客户端:SearchClient.java

package nettytest.udp;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;

/**
 * Created by Lovell on 9/29/16.
 */
/*
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@  @@@@@@@@        @@  @@@@@@@  @@        @@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@  @@@@@  @@@  @@@@@@@@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@@  @@@  @@@@       @@@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@@@  @  @@@@@  @@@@@@@@  @@@@@@@@@  @@@@@@@@@@
 @@@@        @@        @@@@@@   @@@@@@        @@        @@@        @@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 */

public class SearchClient {
    private static Logger logger = LoggerFactory.getLogger(SearchClient.class);

    public static final int MessageReceived = 0x99;
    private int scanPort;

    public SearchClient(int scanPort) {
        this.scanPort = scanPort;
    }

    private static class CLientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
            String  body =  msg.content().toString(CharsetUtil.UTF_8);

            //这里接收到服务端发送的内容
            logger.info("Search, body ==>" + body);
        }
    }

    public void sendPackage() {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new CLientHandler());

            Channel ch = b.bind(0).sync().channel();

            ch.writeAndFlush(new DatagramPacket(
                    Unpooled.copiedBuffer("Searh:", CharsetUtil.UTF_8),
                    new InetSocketAddress("255.255.255.255", scanPort))).sync();

            logger.info("Search, sendPackage()");
            // QuoteOfTheMomentClientHandler will close the DatagramChannel when a
            // response is received.  If the channel is not closed within 5 seconds,
            // print an error message and quit.
            // 等待5秒钟
            if (!ch.closeFuture().await(5000)) {
                logger.info("Search request timed out.");
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.info("Search, An Error Occur ==>" + e);
        }
        finally {
            group.shutdownGracefully();
        }
    }
}

配置常量:AppConstants.java

package nettytest.udp;

/**
 * Created by Lovell on 9/29/16.
 */
/*
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @@@@  @@@@@@@@        @@  @@@@@@@  @@        @@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@  @@@@@  @@@  @@@@@@@@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@@  @@@  @@@@       @@@  @@@@@@@@@  @@@@@@@@@@
 @@@@  @@@@@@@@  @@@@  @@@@@  @  @@@@@  @@@@@@@@  @@@@@@@@@  @@@@@@@@@@
 @@@@        @@        @@@@@@   @@@@@@        @@        @@@        @@@@
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 */

public interface AppConstants {
    int SEARCH_PORT = 5566;
}

来自:http://blog.youkuaiyun.com/hanbin_2015/article/details/50069705

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VCHH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值