一个、Netty解决TCP协议的数据分包的想法



我们知道通过TCP协议发送接收数据时,假设数据过大。接收到的数据会是分包的。比方:

                         
          +-----+-----+-----+

         发送数据是: | ABC | DEF | GHI |

                            +-----+-----+-----+
         而我们想接受到的数据是: | ABCDEFGHI |

该怎样处理这样的情况呢?Netty提供了一个专门处理TCP协议数据的Handler:LengthFieldBasedFrameDecoder ,它的原理是server端和client约定一个协议格式:数据包=协议长度+协议体

      --------------------------------数据包------------------------------

   
 | 协议长度部分(接收数据长度) | 协议体部分(要接收的数据)|

举个样例,假如我们的TCPclient发送了10MB字节的数据,怎样让Nettyserver一次就接收到这10MB数据呢?那就须要client告诉服务端我发送的数据大小是多少,即在发送的数据中增加一个“数据包长度”就可以,上面提到的Handler就是用来和client约定这个协议格式的,它有几个參数,以下我介绍一下它的參数意义:
     int maxFrameLength:定义接收数据包的最大长度,假设发送的数据包超过此值。则抛出异常;
     int lengthFieldOffset:长度属性部分的偏移值,0表示长度属性位于数据包头部。
     int lengthFieldLength:长度属性的字节长度,假设设置为4,就是我们用4个字节存放数据包的长度;
     int lengthAdjustment:协议体长度调节值,修正信息长度,假设设置为4,那么解码时再向后推4个字节。
     int initialBytesToStrip:跳过字节数,如我们想跳过长度属性部分。

二、实例-client发送10MB字节的数据。Netty服务端一次接收到所有10MB数据

client:定义一个消息体,用头部四个字节存放数据包长度

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;
}
private static byte[] intToByteArray(int byteLength, int intValue) {
return ByteBuffer.allocate(byteLength).putInt(intValue).array();
}
private static byte[] combineByteArray(byte[] array1, byte[] array2) {
byte[] combined = new byte[array1.length + array2.length];
System.arraycopy(array1, 0, combined, 0, array1.length);
System.arraycopy(array2, 0, combined, array1.length, array2.length);
return combined;
}

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 }

三、总结:client和服务端定义消息格式必须一致

版权声明:本文博客原创文章。博客,未经同意,不得转载。

示例:Netty 处理 TCP数据分包协议的更多相关文章

  1. netty同端口监听tcp和websocket协议

    前言: 软件通信七层结构(osi模型)中由协议套协议最终组成最高级应用层协议(http等等),下三层结构偏向与数据通信,上三层更偏向于数据处理,中间的传输层则是连接上三层与下三层之间的桥梁,每一层都做 ...

  2. TCP和UDP 协议发送数据包的大小

    在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好? 当然,这个没有唯一答案,相对于不同的系统,不同的要求,其得到的答案是不一样的,这里仅对像ICQ一类的发送聊天消息的情况作分 ...

  3. TCP/IP UDP 协议首部及数据进入协议栈封装的过程

    数据的封装 UDP 封装 TCP 封装 IP 封装 检验和算法 当应用程序用TCP传送数据时,数据被传送入协议栈中,然后逐一通过每一层直到被当作一串比特流送入网络 注: UDP数据TCP数据基本一致. ...

  4. 韩顺刚-tcp报文头协议详细分析第一包数据:序号是0,发送数据的长度是0,因为没有收到对端的数据,所以确认号是0, Syn的标志位设置成1,这里没有发送的数据,只发送TCP的20个字节的头部

    TCP报文段首部格式 大部分TCP报文头部都是20个字节,有的数据包要加上选项. 上面一行代表4个字节,源端口和目的端口都是2个字节. TCP协议是面向字节流的协议 TCP是一段一段分块的发送数据的 ...

  5. Fixed-Length Frames 谈谈网络编程中应用层(基于TCP/UDP)的协议设计

    http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 (2013-04-27 19:11:00 ...

  6. netty(4)高级篇-Websocket协议开发

    一.HTTP协议的弊端 将HTTP协议的主要弊端总结如下: (1) 半双工协议:可以在客户端和服务端2个方向上传输,但是不能同时传输.同一时刻,只能在一个方向上传输. (2) HTTP消息冗长:相比于 ...

  7. 网络基础之 tcp/ip五层协议 socket

    1 网络通信协议(互联网协议) 1.1 互联网的本质就是一系列的网络协议 1.2 osi七层协议 1.3 tcp/ip五层模型讲解 1.3.1 物理层 1.3.2 数据链路层 1.3.3 网络层 1. ...

  8. 东哥讲义2 - 基于TCP,UDP协议的攻击,分析与防护

    TCP SYN FLOOD 攻击 正常的TCP三次握手过程: 处于SYN FLOOD攻击状态时的三次握手过程: 查看示例:x_syn.c文件,一个实现了自定义mac,ip,tcp头部的syn floo ...

  9. Netty处理TCP拆包、粘包

    Netty实践(二):TCP拆包.粘包问题-学海无涯 心境无限-51CTO博客 http://blog.51cto.com/zhangfengzhe/1890577 2017-01-09 21:56: ...

随机推荐

  1. zimbra启用SMTP认证并绑定认证登录和发件人

    1. smtp认证    1.1 修改mynetworks        登录zimbra后台-->全局配置-->MTA-->信任网络-->127.0.0.0/8        ...

  2. 为应用程序池“XX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误

    场景 WCF应用程序部署在IIS7中,使用net.tcp协议对外给几百台客户端提供服务,应用程序池不断崩溃重启. 分析过程 在事件查看器中看到的错误信息类似于 为应用程序池“XX”提供服务的进程在与 ...

  3. 測试之路3——对照XML文件2

    距离上一篇对照xml文件隔了非常久,并不代表一直做了那么久. 事实上上一次对照xml文件一直出错,事实上我忽略了一个非常easy的问题:我从根文件夹下得到的全部孩子,是这个根下的,而xml文件的组织形 ...

  4. jQuery中间each实施例的方法

    $.each()和$(selector).each()很阶段似,但它是不一样的. 前者可用于遍历数组或json对象 后者被设计成遍历jQuery对象 第一个是$.each()对,通常这么用 $.eac ...

  5. WPF DataGrid_SelectChanged获取单元内容

    private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)        {          ...

  6. [Windows]_[0基础]_[使用命令行工具dumpbin分析文件]

    dumpbin(vs拥有) 1. 出口lib函数符号文件(symbols) dumpbin /exports zlib1.lib Microsoft (R) COFF/PE Dumper Versio ...

  7. SQLSERVER图片查看工具SQL Image Viewer5.5.0.156

    原文:SQLSERVER图片查看工具SQL Image Viewer5.5.0.156 SQLSERVER图片查看工具SQL Image Viewer5.5.0.156 在2013年某一次北京SQL ...

  8. 深入了解回调函数Java

    打回来.我第一次看到Java编程思想,后来Observer模式也适用于一个回调函数的想法.但是,一直没有重视,在处于劣势的最终面试,越来越明白为什么那么多人说Java编程思想,这本书应该是一遍又一遍, ...

  9. ZeroBrane Studio远程调试Lua程序(转)

    环境: ZeroBrane Studio安装在Windows 7上,而要调试的程序运行在CentOS上: 设置: 在windows 7上,打开ZeroBrane Studio,打开需要调试的文件,例如 ...

  10. [模式识别].(希腊)西奥多里蒂斯<第四版>笔记8它__模板匹配

      在语音识别方面,同样的话都是同一个人,每次说的情况是不同的,难以识别.本章是定义如何适应不同的情况有不同的特性指标. 1,基于最优路径搜索的度量:①贝尔曼最优性原则和动态编程②编辑距离(The E ...