mina、netty消息边界问题(采用换行符)

在TCP连接开始到结束连接,之间可能会多次传输数据,也就是服务器和客户端之间可能会在连接过程中互相传输多条消息。理想状况是一方每发送一条消息,另一方就立即接收到一条,也就是一次write对应一次read。但是,现实不总是按照剧本来走。

MINA官方文档节选:

TCP guarantess delivery of all packets in the correct order. But there is no guarantee that one write operation on the sender-side will result in one read event on the receiving side. One call of IoSession.write(Object message) by the sender can result in multiple messageReceived(IoSession session, Object message) events on the receiver; and multiple calls of IoSession.write(Object message) can lead to a single messageReceived event.

Netty官方文档节选:

In a stream-based transport such as TCP/IP, received data is stored into a socket receive buffer. Unfortunately, the buffer of a stream-based transport is not a queue of packets but a queue of bytes. It means, even if you sent two messages as two independent packets, an operating system will not treat them as two messages but as just a bunch of bytes. Therefore, there is no guarantee that what you read is exactly what your remote peer wrote.

上面两段话表达的意思相同:TCP是基于字节流的协议,它只能保证一方发送和另一方接收到的数据的字节顺序一致,但是,并不能保证一方每发送一条消息,另一方就能完整的接收到一条信息。有可能发送了两条对方将其合并成一条,也有可能发送了一条对方将其拆分成两条。

对此,MINA的官方文档提供了以下几种解决方案:

1、use fixed length messages

使用固定长度的消息。比如每个长度4字节,那么接收的时候按每条4字节拆分就可以了。

2、use a fixed length header that indicates the length of the body

使用固定长度的Header,Header中指定Body的长度(字节数),将信息的内容放在Body中。例如Header中指定的Body长度是100字节,那么Header之后的100字节就是Body,也就是信息的内容,100字节的Body后面就是下一条信息的Header了。

3、using a delimiter; for example many text-based protocols append a newline (or CR LF pair) after every message

使用分隔符。例如许多文本内容的协议会在每条消息后面加上换行符(CR LF,即"\r\n"),也就是一行一条消息。当然也可以用其他特殊符号作为分隔符,例如逗号、分号等等。

mina server

1
2
3
4
5
6
7
8
IoAcceptor acceptor =newNioSocketAcceptor(); 
        
     // 添加一个Filter,用于接收、发送的内容按照"\r\n"分割 
     acceptor.getFilterChain().addLast("codec",  
             newProtocolCodecFilter((ProtocolCodecFactory)newTextLineCodecFactory(Charset.forName("UTF-8"),"\r\n","\r\n"))); 
        
     acceptor.setHandler((IoHandler)newTcpServerHandle2()); 
     acceptor.bind(newInetSocketAddress(8080));

netty server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ServerBootstrap b =newServerBootstrap(); 
        b.group(bossGroup, workerGroup) 
                .channel(NioServerSocketChannel.class
                .childHandler(newChannelInitializer<SocketChannel>() { 
                    @Override 
                    publicvoidinitChannel(SocketChannel ch) 
                            throwsException { 
                        ChannelPipeline pipeline = ch.pipeline(); 
                           
                        // LineBasedFrameDecoder按行分割消息 
                        pipeline.addLast(newLineBasedFrameDecoder(80)); 
                        // 再按UTF-8编码转成字符串 
                        pipeline.addLast(newStringDecoder(CharsetUtil.UTF_8)); 
                           
                        pipeline.addLast(newTcpServerHandler2()); 
                    
                }); 
        ChannelFuture f = b.bind(8080).sync(); 
        f.channel().closeFuture().sync();

client

1
2
3
4
5
6
7
8
socket = newSocket("localhost",8080); 
            out = socket.getOutputStream(); 
   
            // 请求服务器 
            String lines ="床前明月光\r\n疑是地上霜\r\n举头望明月\r\n低头思故乡\r\n"
            byte[] outputBytes = lines.getBytes("UTF-8"); 
            out.write(outputBytes); 
            out.flush(); 

  

但是这样是有问题的,如果消息内容本身就有换行符,这个肯定是不对的

  原文地址:http://www.cnblogs.com/wucao/p/3936559.html

mina、netty消息边界问题相关推荐

  1. mina、netty消息边界问题(采用换行符)

    在TCP连接开始到结束连接,之间可能会多次传输数据,也就是服务器和客户端之间可能会在连接过程中互相传输多条消息.理想状况是一方每发送一条消息,另一方就立即接收到一条,也就是一次write对应一次rea ...

  2. Netty消息接收类故障案例分析

    <Netty 进阶之路>.<分布式服务框架原理与实践>作者李林锋深入剖析Netty消息接收类故障案例.李林锋此后还将在 InfoQ 上开设 Netty 专题持续出稿,感兴趣的同 ...

  3. 【转】TCP协议的无消息边界问题

    http://www.cnblogs.com/eping/archive/2009/12/12/1622579.html 使用TCP协议编写应用程序时,需要考虑一个问题:TCP协议是无消息边界的,即不 ...

  4. spring集成mina 实现消息推送以及转发

    spring集成mina: 在学习mina这块时,在网上找了很多资料,只有一些demo,只能实现客户端向服务端发送消息.建立长连接之类.但是实际上在项目中,并不简单实现这些,还有业务逻辑之类的处理以及 ...

  5. Apache mina,Netty的起源和历史

    Genesis of MINA    by Trustin Lee   文章来自:Apache mina   http://mina.apache.org/mina-project/road-map. ...

  6. netty消息分发思路

    首先在消息中定义一个关于消息的名称 比如login regist这种类似的. 然后使用spring,将一些处理类继承runnable接口,然后添加@component注解,并命名为相应的命令. 接着在 ...

  7. Netty进阶 黏包与半包问题的处理,数据解码器详解

    概述 假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到的字节数是不确定的,故可能存在以下情况. (1)服务端一次接收到了两个数据包,D1和D2粘合在一起,被称为TCP黏包: (2 ...

  8. Mina、Netty、Twisted一起学(五):整合protobuf

    protobuf是谷歌的Protocol Buffers的简称,用于结构化数据和字节码之间互相转换(序列化.反序列化),一般应用于网络传输,可支持多种编程语言. protobuf怎样使用这里不再介绍, ...

  9. Mina、Netty、Twisted一起学(一):实现简单的TCP服务器

    MINA.Netty.Twisted为什么放在一起学习?首先,不妨先分别看一下它们官方网站对其的介绍: MINA: Apache MINA is a network application frame ...

最新文章

  1. xargs 主要用于不支持管道的shell命令*****
  2. JavaScript文档
  3. 【二分图判定】hdu3478 Catch
  4. android 相机 全功能,一加7系首个Android 11公测代码暗示了相机应用的诸多功能更新...
  5. 前端写分页(用了自己同事写的插件)
  6. 我的软考之路(六)——数据结构与算法(4)之八大排序
  7. 【Kettle】创建资源库用户
  8. IDEA 代码格式化
  9. android 版本 6.0升级包,EMUI 6.0系统刷机包
  10. mac上好看的时钟屏保
  11. html自动切换图片特效代码,js图片自动切换效果处理代码
  12. 火爆全网的动态曲线图是怎么做的?
  13. win10家庭版系统 修改docker为国内镜像
  14. Excel:筛选列数据,不同值
  15. 2020.2.18 大一寒假训练十一(set)
  16. 2019年最佳黑客书籍 - 初级到高级
  17. 主成分分析(PCA)与矩阵奇异值分解(SVD)
  18. python 正则表达式
  19. 对乔布斯逝世的47个评价
  20. 蚁群算法解决车间调度问题

热门文章

  1. 前后端分离项目_七个开源的 Spring Boot 前后端分离项目,一定要收藏
  2. 计算机技术应用及信息管理,计算机应用技术与信息管理整合研究(共2808字).doc...
  3. mysql2014授权设置_SQLServer2014许可证(六)虚拟化中的授权
  4. dedecms php5.4 无法退出后台,解决更换PHP5.4以上版本后Dedecms后台登录空白问题的方法...
  5. ipmitool 设置网关_IPMI (Intelligent Platform Management Interface)
  6. springmvc 加载 慢_怎么加载spring框架这么慢是不是配置…-就业班
  7. html一半文字一半图片,一个div的子div宽是200高是350 里面怎么让图片显示一半 另外一半文字居中!?...
  8. 灰度值取值范围_一幅灰度图像,用8bit量化,取值范围为[0,255],其中0表示(),255表示()。...
  9. java%3e%3e=符号_android中一些特殊字符(如:←↑→↓等箭头符号)的Unicode码值...
  10. 学计算机的女生是一种怎样的存在?