tcp拆包、粘包

三次握手、四次挥手

tcp连接要经历三次握手,断开要经历四次挥手

传统的socket编程缺点:

1、一个客户端连接开启一个线程,占用资源比较多

2、三次握手是比较耗时的,通信效率低

NIO 在TCP 点对点的通信基础上,服务端实例化一个ServerSocketChannel,创建一个多路复用Selector,客户端实例化SocketChannel,注册到Selector,Selector轮询所有的Channel(通道),通过Channel的状态执行以下四种(accept,connect,read,write)操作。

Java NIO的基本思想就是用一个线程来处理多个Channel。它提供了一套网络API,可以用来处理连接数很多的情况,但是NIO的API是非常繁琐的,实际工作中是不会使用NIO的API,而是使用框架netty的API。

TCP拆包与粘包

TCP粘包是指一次接收的数据不能完全地体现一个完整的消息数据。TCP通讯为何存在粘包呢?

tcp是一个流式协议,所谓流,就是没有界限的一串数据。就像河里的流水,是连成一片的,没有分界线。tcp底层并不了解上层数据的具体含义,它会根据tcp缓冲区的实际情况进行包的划分。所以在业务上认为,一个完整的包有可能被tcp拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的tcp拆包、粘包问题。

处理粘包的唯一方法就是制定应用层的数据通讯协议,通过协议来规范现有接收的数据是否满足消息数据的需要。netty提供三种方法:

1、分隔符解码器 DelimiterBasedFrameDecoder

如尾部加上特殊字符接收,如$_

2、定长解码器 FixedLengthFrameDecoder

如5位定长字符串接收,够长度就发送,如果不够可以用空格补位,否则可能造成数据丢失

3、自定义协议,为了安全或者处理个性化业务,将消息分为消息头和消息体,在消息头中包含消息总长度的字段,然后进行业务逻辑的处理

消息序列化

java序列化的硬伤太多,比如序列化后的码流太大,序列化性能太低,生产可以选择的序列化框架有:

1、jboss masharling:使用Jboss的Marshalling包,它对jdk默认的序列化框架做了优化。Server和Client里需要加上以下Marshalling编解码,可以直接解析java对象:

MarshallingCodeCFactory.buildMarshallingDecoder()
MarshallingCodeCFactory.buildMarshallingEecoder()

2、google protobuf

3、facebook thrift

netty最佳实践

 

数据通信,心跳检测

ServerHandler端writeAndFlush之后调用.addListener(ChannelFutureListener.CLOSE);可以在数据冲刷之后关闭客户端连接

 

你可能感兴趣的:(网络通信)