mina源码阅读之编码与解码

TCP是一个流协议,所谓流协议就是没有界限的一串数据,数据之间并没有分界线,它会根据TCP缓冲区的实际大小进行包的划分,那么业务上的一个完整包可能会被TCP拆成多个包进行发送,也有可能把多个小的包封装成一个大包进行发送,这时候就可能发生拆包与粘包。对于接收端来说,由于数据并没有界限,接收端不知道到底什么时候数据算是读取完,也只能根据缓冲区的大小来进行包的划分,此时接收端也可能会发生拆包与粘包。
针对TCP流协议的特性,有三种常用的方法可解决拆包与粘包的问题。
1、因为包与包之间没有界限才会导致无法判断是否读取到了一个完整的包,因此可在发送端和接收端定义一个相同的分隔符,发送端在发送数据的时候,包与包之间用该分隔符隔开,这样接收端读取到对应的分隔符就认为读取到了一个完整的包,就可以继续下一步操作了。
2、消息定长,比如每个报文的大小固定为200字节,如果不够空位补齐。
3、在数据中的某个位置使用一个字段,表示数据的长度,类似Http协议中的Content-Length表示消息正文的长度。
发送端使用以上三种方法中的一种来使原本没界限的数据变的有规律可循,这个过程就是我们常说的编码。对应的在接收端,根据发送端数据的规律解析数据的过程叫解码。
mina底层使用的协议就是TCP,TCP传输过程中的数据都是二进制数据,服务端和客户端程序中使用的都是Java对象,那么必然有一个将Java对象变成二进制数据和将二进制数据解析成Java对象的过程,这个过程中很可能就会出现粘包与拆包的问题。那么为了解决TCP通信过程中产生的粘包、拆包问题,需要在发送方就要让Java对象按照某种规律变成二进制数据,然后接收方根据同样的规律将二进制数据解析成Java对象,这两个过程分别对应编码和解码过程。
为了实现在发送数据之前对数据按照某种规律进行编码,我们需要实现自己的编码器。在mina中实现编码器是一件简单且愉快的事情,我们只需实现ProtocolEncoder接口,但是有更简便的方法,直接继承ProtocolEncoderAdapter类,实现encode方法即可。
同理,为了对接收到的数据按照约定的规律进行解码,我们需要实现自己的解码器。在mina中实现解码器只需实现ProtocolDecoder接口,更简洁的方法就是继承ProtocolDecoderAdapter类,实现decode方法即可。

你可能感兴趣的:(mina)