【初学与研发之NETTY】netty3之传送字符串以及超长字符串的问题

本文介绍了如何使用Netty实现客户端和服务端之间的字符串传输,并详细解释了如何通过更改编解码方式来解决长字符串被截断的问题。

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

使用netty主要用于建立客户端、服务端,在两者发送字符串(字节)、文件或者对象等,来满足在应用中的需求,这里先说下字符串的传送。个人认为,netty的传送什么都不重要,重要的是采用什么样的转码、解码方式。本人在做日志分析组件的过程中开始将日志信息以字符串的形式通过客户端传送给服务端,主要的代码片段如下:

客户端:

[java] view plain copy

 print?

  1. //客户端通道和尝试连接的帮助类  
  2.             bootstrap = new ClientBootstrap(  
  3.                     new NioClientSocketChannelFactory(  
  4.                             Executors.newCachedThreadPool(),   
  5.                                 Executors.newCachedThreadPool()));  
  6.               
  7.             //配置一个子channel pipeline  
  8.             bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  9.                 public ChannelPipeline getPipeline() {  
  10.                     ChannelPipeline pipeline = Channels.pipeline();  
  11.                     pipeline.addLast("decoder", new StringDecoder());  
  12.                     pipeline.addLast("encoder", new StringEncoder());  
  13.                     pipeline.addLast("handler", new LogClientHandler());  
  14.                     return pipeline;  
  15.                 }  
  16.             });  
  17.             // 配置channel的选项集  
  18.             bootstrap.setOption("tcpNoDelay", true);  
  19.             bootstrap.setOption("keepAlive", false);  
  20.             //连接超时时间为3s  
  21.             bootstrap.setOption("connectTimeoutMillis", 3000);  


LogClientHandler没有什么特别的处理。

服务端:

[java] view plain copy

 print?

  1. //接受传入连接的帮助类  
  2.         bootstrap = new ServerBootstrap(  
  3.                 new NioServerSocketChannelFactory(  
  4.                         Executors.newCachedThreadPool(),  
  5.                             Executors.newCachedThreadPool()));  
  6.           
  7.         //配置一个子channel pipeline  
  8.         //每个channel都会拥有自己的ChannelPipeline  
  9.         bootstrap.setPipelineFactory(new ChannelPipelineFactory() {  
  10.             public ChannelPipeline getPipeline()  {  
  11.                 ChannelPipeline pipeline = Channels.pipeline();  
  12.                 pipeline.addLast("decoder", new StringDecoder());  
  13.                 pipeline.addLast("encoder", new StringEncoder());  
  14.                 //处理业务逻辑的帮组类  
  15.                 pipeline.addLast("handler", new LogServerHandler());  
  16.                 return pipeline;  
  17.             }  
  18.         });  
  19.         //配置通道  
  20.         // 子channel的属性集  
  21.         //设置缓存区大小20M  
  22.         bootstrap.setOption("child.receiveBufferSize", 1048576*20);  
  23.         bootstrap.setOption("child.keepAlive", false);  
  24.         bootstrap.setOption("child.tcpNoDelay", true);  
  25.         //创建一个绑定到指定的本地地址的channel  
  26.         bootstrap.bind(configInet(host, port));  

LogServerHandler中messageReceived(ChannelHandlerContext ctx, MessageEvent e)直接接受客户端发送的字符串。

netty中在传送字符串的长度有限制,貌似超过1024个字节就截断了,导致接收的信息部完整,经查阅后可采用传送字节数组的方式来解决这个问题:

1、首先在客户端、服务端将转码、解码的方式修改成如下:

    pipeline.addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
    pipeline.addLast("encoder", new LengthFieldPrepender(4, false));

 

2、客户端传送字符串时需要这样:

      ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
       
       buffer.writeBytes(log.getBytes(ConstantSet.CHAR_DECODER));
       
       //当与远程端建立连接以后即刻发送日志信息
       channel.write(buffer);

       buffer.clear();

 

3、服务端接收字符串:

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
   throws Exception {
         //添加到日志队列中
        ChannelBuffer buffer = (ChannelBuffer)e.getMessage();
        String log = buffer.toString(Charset.forName(ConstantSet.CHAR_DECODER));
}

注:上述的字符串与字节数组转换时,采用的字符集编码请保持一致。

转载于:https://my.oschina.net/sniperLi/blog/913453

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值