一.Netty解决TCP协议数据分包问题思路
我们知道通过TCP协议发送接收数据时,如果数据过大,接收到的数据会是分包的,比如:
+-----+-----+-----+
发送数据是: | ABC | DEF | GHI |
+-----+-----+-----+
而我们想接受到的数据是: | ABCDEFGHI |
该如何处理这种情况呢?Netty提供了一个专门处理TCP协议数据的Handler:LengthFieldBasedFrameDecoder ,它的原理是服务器端和客户端约定一个协议格式:数据包=协议长度+协议体
--------------------------------数据包------------------------------
| 协议长度部分(接收数据长度) | 协议体部分(要接收的数据)|
举个例子,假如我们的TCP客户端发送了10MB字节的数据,如何让Netty服务器一次就接收到这10MB数据呢?那就需要客户端告诉服务端我发送的数据大小是多少,即在发送的数据中加入一个“数据包长度”即可,上面提到的Handler就是用来和客户端约定这个协议格式的,它有几个参数,下面我介绍一下它的参数意义:
int maxFrameLength:定义接收数据包的最大长度,如果发送的数据包超过此值,则抛出异常; int lengthFieldOffset:长度属性部分的偏移值,0表示长度属性位于数据包头部; int lengthFieldLength:长度属性的字节长度,如果设置为4,就是我们用4个字节存放数据包的长度; int lengthAdjustment:协议体长度调节值,修正信息长度,如果设置为4,那么解码时再向后推4个字节; int initialBytesToStrip:跳过字节数,如我们想跳过长度属性部分。
二.实例-客户端发送10MB字节的数据,Netty服务端一次接收到全部10MB数据
客户端:定义一个消息体,用头部四个字节存放数据包长度
public byte[] send(byte[] sendData) throws UnknownHostException, IOException { Socket socket = new Socket(serverIp, serverPort); OutputStream os = socket.getOutputStream(); InputStream is = socket.getInputStream(); byte resultArray[] = null; try { // 定义一个发送消息协议格式:|--header:4 byte--|--content:10MB--| // 获取一个4字节长度的协议体头 byte[] dataLength = intToByteArray(4, sendData.length); // 和请求的数据组成一个请求数据包 byte[] requestMessage = combineByteArray(dataLength, sendData); //发送数据------------------------------- os.write(requestMessage); os.flush(); //接收数据------------------------------- resultArray = IOUtils.toByteArray(is); } catch (Exception e) { e.printStackTrace(); } finally { os.close(); is.close(); socket.close(); } return resultArray; }
Netty服务端:定义一个LengthFieldBasedFrameDecoder(1024*1024*1024, 0, 4,0,4)),最大数据量是1GB,长度属性位于数据包头部,占4个字节,协议体调节值为0,跳过头部协议长度四个字节
@Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("framedecoder",new LengthFieldBasedFrameDecoder(1024*1024*1024, 0, 4,0,4)); pipeline.addLast(new TCPServiceHandler());// 处理业务Handler }
三.总结:客户端和服务端定义消息格式必须一致
文章来源:http://blog.csdn.net/suifeng3051/article/details/34444585
相关推荐
这些编解码器能够自动处理数据的分包和粘包问题,简化了协议处理的复杂性。 4. **EventLoop与EventLoopGroup**:Netty 使用事件驱动模型,EventLoop是单线程的事件处理器,负责处理I/O事件和执行任务。...
***ty的特点和优势:Netty拥有多种功能和特点,比如高效的I/O线程模型,可配置的线程池,以及对TCP粘包/分包、SSL/TLS协议、编解码器等的内置支持。Netty还提供了一套丰富的协议栈实现,比如HTTP、WebSocket等。它也...
在TCP/IP通信中,由于TCP协议的流式传输特性,数据可能会被打包成多个TCP段发送,接收端可能会接收到多个数据包连续到达,这就产生了“粘包”和“分包”的问题。当发送端发送的数据大小不固定时,如果不做处理,接收...
3. 帧解码与编码:Netty 提供了多种预定义的 FrameDecoder 和 FrameEncoder,如 LengthFieldBasedFrameDecoder,用于处理不同协议的数据分包。 4. 零拷贝:Netty 支持零拷贝技术,减少数据在内存间的复制,提高传输...
《构建视频聊天服务器:基于...总结起来,构建基于UDP的Netty视频聊天服务器是一项涉及网络协议、数据处理、性能优化等多个技术领域的综合性工作。理解并掌握这些知识点,对于开发高效、稳定的实时通信应用至关重要。
在TCP协议中,由于其流式传输的特点,可能会出现多个数据包被合并成一个大的数据包发送,或者一个数据包被拆分成多个小的数据包发送,这就是所谓的“粘包”或“拆包”问题。在Unity中,如果不对数据进行适当的分包和...