netty+udp协议 服务端接收消息(带中文消息)
前言:这近几天要做一个netty+udp协议做服务端放到腾讯云中,提供给合作公司上传流媒体数据。
1:netty版本
dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.12.Final</version> </dependency>
下面遇到的几个坑。
1:端口问题。同事帮忙在腾讯云中开方的端口9701,当时没注意看。给我开的端口9701协议是TCP的。导致我测试时在本地一直 ok,部署到云服务器收到不到信息。(这个比较坑)
2:合作公司上传的数据可能有中文(虽然再三确认,没有中文。为了保险还是支持中文)
总结:例子比价简单。我写博客,会把自己遇到的问题也列出来,避免他人入坑。
package park.mecdaemons.bussiness; import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import java.nio.charset.Charset; import java.util.concurrent.*; @Service @Component @Slf4j public class UdpEventServer implements ApplicationRunner{ private int port = 9701; @Override public void run(ApplicationArguments args) throws Exception { log.info("解析数据开始UdpEventServer..run()"); //开启线程,执行接收处理方法 ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("wbAdjust-%d").build(); ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024), factory, new ThreadPoolExecutor.AbortPolicy()); singleThreadPool.execute(this::doWork); } /** * @return void * @Author fxk * @Param [] * @Description : 数据接收线程 方法实现udp上传数据的接收,并将实现数据处理handler * @Date 2020/10/15 17:00 **/ private void doWork() { log.info("解析数据开始UdpEventServer..doWork()...1"); try { EventLoopGroup group = new NioEventLoopGroup(); Bootstrap b = new Bootstrap(); //由于我们用的是UDP协议,所以要用NioDatagramChannel来创建 b.group(group) .channel(NioDatagramChannel.class) .option(ChannelOption.SO_BROADCAST, true)//支持广播 .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535)) .handler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); //设置处理handler.执行具体处理方法 pipeline.addLast(new updHandler()); } }); b.bind(port).sync().channel().closeFuture().await(); log.info("解析数据开始UdpEventServer..doWork()...4"); } catch (InterruptedException e) { e.printStackTrace(); log.error("执行udp接收服务出错" + e.getMessage()); } } }
@Slf4j public class updHandlerextends SimpleChannelInboundHandler<DatagramPacket> { private static final Charset CHARSET = Charset.forName("GBK"); @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { try { log.info("ChineseProverbServerHandler..channelRead0()"); //获取消息的ByteBuf ByteBuf buf = msg.copy().content(); //获取接收到的字节流转为string 这个网上有很多方法,但试了很多,还是这个可以解决中文乱码 String content = (String) buf.readCharSequence(buf.readableBytes(), CHARSET); log.info("客户端消息111" + "==>" + content); //通知客户端 //ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("结果:", CharsetUtil.UTF_8), msg.sender())); //todo 写具体的解析处理方法 } catch (Exception e) { log.error("类 ChineseProverbServerHandler 出错" + e.getMessage()); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); }
在云端服务器执行接口