mina、netty消息边界问题
来源:互联网 发布:怎么找淘宝高仿鞋店铺 编辑:程序博客网 时间:2024/05/18 23:55
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
IoAcceptor acceptor =
new
NioSocketAcceptor();
// 添加一个Filter,用于接收、发送的内容按照"\r\n"分割
acceptor.getFilterChain().addLast(
"codec"
,
new
ProtocolCodecFilter((ProtocolCodecFactory)
new
TextLineCodecFactory(Charset.forName(
"UTF-8"
),
"\r\n"
,
"\r\n"
)));
acceptor.setHandler((IoHandler)
new
TcpServerHandle2());
acceptor.bind(
new
InetSocketAddress(
8080
));
netty server
ServerBootstrap b =
new
ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.
class
)
.childHandler(
new
ChannelInitializer<SocketChannel>() {
@Override
public
void
initChannel(SocketChannel ch)
throws
Exception {
ChannelPipeline pipeline = ch.pipeline();
// LineBasedFrameDecoder按行分割消息
pipeline.addLast(
new
LineBasedFrameDecoder(
80
));
// 再按UTF-8编码转成字符串
pipeline.addLast(
new
StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast(
new
TcpServerHandler2());
}
});
ChannelFuture f = b.bind(
8080
).sync();
f.channel().closeFuture().sync();
client
socket =
new
Socket(
"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消息边界问题
- Mina、Netty、Twisted一起学(二):TCP消息边界问题及按行分割消息
- MINA、Netty、Twisted一起学(二):TCP消息边界问题及按行分割消息
- Mina解码边界问题的处理
- netty vs mina
- java NIO: MINA, Netty
- Mina和Netty
- Mina和Netty
- Mina、Netty的比较
- netty vs mina
- Apache mina VS Netty
- Netty vs Mina
- 边界问题
- Mina、Netty、Twisted一起学(三):TCP消息固定大小的前缀(Header)
- MINA、Netty、Twisted一起学(三):TCP消息固定大小的前缀(Header)
- netty vs mina netty和mina的区别
- netty和mina的比较
- Netty & Mina 入门级总结
- 关于WEB-INF目录下无法访问webapp下的css等静态文件
- 选择排序、插入排序 的思想(java)
- Centos6.X搭建Squid为YUM做代理
- linux 系统上安装或自动更新安全补丁
- 【毕业季】这篇文章让我再次转正,关于运营那些事
- mina、netty消息边界问题
- java实现Lucene索引搜索
- RTMP流媒体播放协议简单分析
- 计算机视觉caffe之路第五篇:ImageNet数据集训练及预测实例
- Java面向对象特征有那些
- [ERROR] [FATAL] InnoDB: Missing MLOG_FILE_NAME or MLOG_FILE_DELET ...... 5.7的bug
- RN点击事件的使用
- 使用Android自带的material design图标
- Github入门实践