IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> tcp组包1——为啥要组包 -> 正文阅读

[网络协议]tcp组包1——为啥要组包

本文主要介绍下,如果不进行组包的时候,会出现什么情况:
下面是服务端,一次性发送1000条数据:

public void AddProtocolMessage()
        {
            Google.Protobuf.Examples.Person.Person person = new Google.Protobuf.Examples.Person.Person();
            person.Id = 1;
            person.Name = "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axxiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好a你好aiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a" +
                "xiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好axiaoming你好a你好a";
            person.Email = "xiaoming@163.com";

            Google.Protobuf.Examples.Person.Person.Types.PhoneNumber phoneNumber = new Google.Protobuf.Examples.Person.Person.Types.PhoneNumber();
            phoneNumber.Number = "123456";
            phoneNumber.Type = Google.Protobuf.Examples.Person.Person.Types.PhoneType.Mobile;
            person.Phones.Add(phoneNumber);

            MemoryStream ms = new MemoryStream();
            Google.Protobuf.CodedOutputStream codedOutput = new Google.Protobuf.CodedOutputStream(ms);
            person.WriteTo(codedOutput);
            codedOutput.Flush();
            byte[] buffer = ms.GetBuffer();
            long len = ms.Length;
            Message message = new Message();
            message.m_data = buffer;
            for (int i = 0; i < 1000; ++i)
            {
                m_sendMessages.Enqueue(message);
            }
        }

客户端在接收的地方:

        static int count = 0;
        static int totalSize = 0;
        private void OnReceiveCallback(IAsyncResult ar)
        {
            Socket sock = (Socket)ar.AsyncState;
            int len = sock.EndReceive(ar);
            totalSize += len;
            Console.WriteLine("receive=" + count++ + "  len=" + len + "  totalSize=" + totalSize);
            //m_receiveStream.Write(m_receiveBuffer, 0, len);
            //m_receiveStream.Seek(0, SeekOrigin.Begin);
            //Google.Protobuf.Examples.Person.Person person = Google.Protobuf.Examples.Person.Person.Parser.ParseFrom(m_receiveStream);
            m_clientSocket.BeginReceive(m_receiveBuffer, 0, m_receiveBuffer.Length, SocketFlags.None, OnReceiveCallback, m_clientSocket);
        }

这里的m_receiveBuffer我们开的是128
在这里插入图片描述
服务器总共发送了1000次,而客户端接收了13204次,最后一次接收的大小是16字节。总量是不变的。1690000字节。

而我们的协议呢?是1690个字节,所以在接收的地方,要将多次接收到的数据组装成一个有效的数据包才行。

那我们想,如果是不是buffer开的大一点,就好了,于是我们开成4096个字节大小。
在这里插入图片描述

服务端发送了1000次,但是客户端本次接收了964次,咦?
接收的次数小于了发送的次数,那说明,比如有一次接收的字节数大于发送的字节数1690个字节。
在这里插入图片描述
果然,红色框内接收的字节数大于发送的1690个字节。

所以这就说明了,buffer开的大和开的小,都不能准确的定义,一次接收的数据就是一个完整的包,有可能是大于一个包,也可能是小于一个包。
故,必须标记一个包的大小,然后根据包的大小去组装成一个有效包。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-11-16 19:11:36  更:2021-11-16 19:13:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:30:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码