Netty框架:java实现单播

package com.cetcnav.GR.business.server;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cetcnav.GR.base.utils.CommonUtils;
import com.cetcnav.GR.base.utils.PropertiesUtils;
import com.cetcnav.GR.business.code.UDPDeCoder;

import cn.hutool.core.lang.Console;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
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.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.CharsetUtil;

/**
 * @author wp 2021年5月13日上午9:07:49 GRDatacenter UDPSingleServer.java
 *         类说明:构建UDP单播模式服务端 (星历)
 */
public class UDPSingleServer implements Runnable {
	private static Logger log = LoggerFactory.getLogger(UDPSingleServer.class);

	// 获取UDP ip
	private static final String IP = PropertiesUtils.getString("udp.client.single.ip");
	// 获取UDP port
	private static final int PORT = PropertiesUtils.getInteger("udp.client.single.port");
	private static EventLoopGroup group = new NioEventLoopGroup();
	private static Bootstrap server;
	private static ChannelFuture future;

	@Override
	public void run() {
		init();

	}

	public static void init() {
		server = new Bootstrap();
		server.option(ChannelOption.SO_KEEPALIVE, true);
		server.group(group).channel(NioDatagramChannel.class).remoteAddress(IP, PORT)
				.handler(new ChannelInitializer<NioDatagramChannel>() {
					@Override
					protected void initChannel(NioDatagramChannel ch) throws Exception {
						ChannelPipeline cp = ch.pipeline();
						cp.addLast("log", new LoggingHandler(LogLevel.INFO));
						cp.addLast("decoder", new UDPDeCoder());
						cp.addLast("handler", new UDPSingleServerHandler());
					}
				});
		try {
			// ChannelFuture f = server.bind(0).sync();
			future = server.connect(IP, PORT).sync();
			future.channel().writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("1111", CharsetUtil.UTF_8),
					new InetSocketAddress(IP, PORT))).sync();
			if (future.isSuccess()) {
				log.info("启动UDP单播(星历)连接成功,:" + IP + ":" + PORT);
			} else {
				log.info("启动UDP单播(星历)连接失败");
			}
			future.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			Console.error(e.getMessage());
			e.printStackTrace();
		} finally {
			group.shutdownGracefully();
		}
	}

	/**
	 * 作为客户端定时向服务发送,以保持联系
	 */
	public static void UDPSingleServerKeepalive() {
		while (true) {
			if (future == null) {
				continue;
			}
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			// System.out.println(123);
			try {

				future.channel().writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("1111", CharsetUtil.UTF_8),
						new InetSocketAddress(IP, PORT))).sync();
			} catch (InterruptedException e) {
				System.out.println(CommonUtils.printStackTrack(e));

			}
		}
	}

}

import java.sql.Timestamp;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cetcnav.GR.base.utils.ByteConvertUtil;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.codec.MessageToMessageDecoder;

/**
 * @author wp
 * @date 2021年6月3日下午7:47:43
 * @projectName GRDatacenter
 * @fileName UDPDeCoder.java
 * @tags 类说明:接收到星历 解析
 */
public class UDPDeCoder extends MessageToMessageDecoder<DatagramPacket> {
	private static Logger log = LoggerFactory.getLogger(UDPDeCoder.class);

	@Override
	protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
		ByteBuf in = msg.content();
		// 信息总长度
		int overallLength = in.readableBytes();
		log.info("收到星历数据总长度为:" + overallLength + "字节");
		if (overallLength < 12) {
			log.info("收到数据总长度小于约定协议基础长度,非法数据!");
			in.skipBytes(in.readableBytes());
			return;
		}

		in.markReaderIndex();
		byte[] bytes = new byte[overallLength];
		in.readBytes(bytes);
		String hexStr = ByteConvertUtil.bytes2HexString(bytes);
		log.info("接收到星历原始数据信息:" + hexStr);
		in.resetReaderIndex();

		EphemerisTransmissionInstruction msg1 = new EphemerisTransmissionInstruction();
		msg1.setDataLen(bytes.length);
		msg1.setOrginData(bytes);
		msg1.setRecevieTime(new Timestamp(System.currentTimeMillis()));
		out.add(msg1);
		in.skipBytes(in.readableBytes());

	}

}

import java.net.InetSocketAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cetcnav.GR.business.cache.EphemerisTransmissionInstructionCache;
import com.cetcnav.GR.business.cache.UDPChannelManager;
import com.cetcnav.GR.business.code.EphemerisTransmissionInstruction;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * @author wp
 * @date 2021年6月3日下午7:58:20
 * @projectName GRDatacenter
 * @fileName UDPSingleServerHandler.java
 * @tags 类说明:
 */
public class UDPSingleServerHandler extends ChannelInboundHandlerAdapter {
	private static Logger log = LoggerFactory.getLogger(UDPSingleServerHandler.class);

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		// 星历传输指令
		if (msg instanceof EphemerisTransmissionInstruction) {
			EphemerisTransmissionInstructionCache.add((EphemerisTransmissionInstruction) msg);
		}
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		// ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
		// .addListener(ChannelFutureListener.CLOSE);
		ctx.flush();
		// System.out.println("信息接收完毕...");
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		// 当出现异常就关闭连接
		log.info("当出现异常就关闭连接");
		cause.printStackTrace();
		ctx.close();
	}

	/**
	 * 客户端与服务端创建连接的时候调用
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		ctx.fireChannelActive();
		// ctx.channel().writeAndFlush("");
		UDPChannelManager.addChannel(ctx.channel());
	}

	/**
	 * 客户端与服务端断开连接时调用
	 */
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		InetSocketAddress inetSocket = (InetSocketAddress) ctx.channel().remoteAddress();
		String ip = inetSocket.getAddress().getHostAddress();
		int port = inetSocket.getPort();
		log.info("客户端(ip:" + ip + " port:" + port + ")与服务端连接关闭...");
		UDPChannelManager.group.remove(ctx.channel());
	}

}

	
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值