TCP编程流程和粘包

目录

1、TCP编程流程

 2、粘包


1、TCP编程流程

 

socket() 是创建套接字,返回值为监听套接字描述符,有了套接字才能通过网络进行数据的传输。创建套接字的参数要指定服务类型,TCP协议使用的是流式服务(SOCK_STREAM)。

bind() 是指定套接字使用的IP和端口。IP地址 是自己主机的地址。端口 是一个16位整型值, 一般0~1024为知名端口,一般用户不能随便使用;1024~4096为保留端口,一般不使用;4096以上为临时端口,可以使用。在Linux系统上,1024以内的端口号只有root用户可以使用。

listen() 是创建监听队列。监听队列有两种,一个是存放未完成三次握手的连接,一种是存放已完成三次握手的连接。该函数的第二个参数在Linux系统上是指已完成三次握手队列的长度,在Unix系统上是未完成和已完成三次握手队列总和的大小。

accept() 是处理放在 listen() 创建的已完成三次握手队列中的连接。每处理一个连接,accept()返回一个该连接对应的连接套接字描述符,如果已完成三次握手队列为空,则accept阻塞。

 

connect() 一般由客户端程序执行,需要指定连接的服务端的IP和端口。该方法执行后,会进行三次握手,建立连接

三次握手(建立连接)

send() 是用来向TCP连接的对端发送数据。send()执行成功,说明成功将数据写入发送端的发送缓冲区中,并不能说明已经发到对端。返回值为实际写入发送缓冲区的数据长度。

recv() 是用来接收TCP连接的对端发送的数据。recv()从自己的接收缓冲区中读取数据,如果接收缓冲区中没有数据,就会阻塞。返回值为实际读取的字节数。

recv()返回值为0是对端关闭TCP连接的唯一标识。

close() 可用来关闭文件的,该处用于关闭套接字和TCP连接。

关闭TCP链接:自己端执行该方法后,在对端未执行close()时,进行两次挥手,此时处于半连接状态;当对端也执行close()后,再进行后两次挥手,最终完成四次挥手。

四次挥手(断开连接)

 2、粘包

对6.2服务端代码中的recv()函数的参数从127改为1,即一次recv一个字符。

客户端发送一个 "hello" ,服务端将会把hello每个字符换行打印一次,客户端收到一个 "ok" ;当客户端再发送数据后,将会收到四个 "ok" 。如下图:

 

 

原因:首先明确程序的循环运行速度要小于服务端将数据从其发送缓冲区传递到客户端的接收缓冲区。recv()和send()都是从接收缓冲区和发送缓冲区中读取数据,并不意味着把数据发给对方或者从对方处接收到数据。

当服务端recv()第一个字符 ‘h’ 后,此时客户端的recv()正处于阻塞状态(客户端的接收缓冲区为空),send()一个 "ok" 到发送缓冲区并传递给客户端的接收缓冲区,还没等到服务端recv()第二个字符 ‘e’ 后send()第二个 "ok" ,客户端就已经recv()了其接收缓冲区中的 “ok” ,此时客户端的接收缓冲区只有一个 “ok” 。客户端recv()后阻塞在fgets()函数处,等待输入数据。等待过程中,服务端也已经将剩下的四个字符对应的四个 "ok" 陆陆续续发送到客户端的接收缓冲区中,当客户端刚recv()第二个数据后,就会立即读取接收缓冲区中的四个 "ok" ,将其打印出来。

查看缓冲区的数据字节大小命令:netstat -natp

 

 

出现这种数据粘连在一起无法区分第几次发送的情况即为粘包

粘包的概念:TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包

产生粘包的原因:

1、TCP是基于字节流的,虽然应用层和传输层之间的数据交互是大小不等的数据块,但是TCP把这些数据块仅仅看成一连串无结构的字节流,没有边界; 2、在TCP的首部没有表示数据长度的字段,基于上面两点,在使用TCP传输数据时,才有粘包或者拆包现象发生的可能。

粘包/拆包发生的原因:

发生TCP粘包或拆包有很多原因,现列出常见的几点: 1、要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。 2、待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。 3、要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包。 4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。

TCP 字节流的特点:发送端执行的写操作次数和接收端执行的读操作次数之间没有任何数量关系,应用程序对数据的发送和接收是没有边界限制的。

 

粘包对于数据下载没有影响,只需要将数据全部收到就可以;而在交互时需要发送次数与接收次数对应。

粘包的简单解决办法:

1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。

2、在数据前后加上标志,对方接收到数据后进行检查数据是否完整。3、发送端将每个数据包封装为固定长度(不够的可以通过补0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1254.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库系统 - 家庭教育平台设计开发

目录 1.绪论 1.1项目背景 1.2家庭教育平台的发展现状与优势 1.2.1国内外发展现状 1.2.2家庭教育平台的优势 2.需求分析 2.1可行性分析 2.1.1经济可行性 2.1.2 技术可行性 2.1.3操作可行性 2.2系统功能 2.2.1 家庭教育资源 2.2.2 家庭教育指导师 2.2.3家庭教育咨询…

BUG解决Button类不能从UnityEngine.UI中引用

Button does not contain a definition for onClick and no accessible extension method onClick accepting a first argument of type Button could be found (are you missing a using directive or an assembly reference?) 一个非常奇葩的问题;突然!!!!! using UnityEn…

redis如何实现持久化

RDB快照 RDB是一种快照存储持久化方式,具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为dump.rdb,而在Redis服务器启动时,会重新加载dump.rdb文件的数据到内存当中恢复数据。 开启RDB持久化方式 开启…

AWS MSK集群认证和加密传输的属性与配置

通常,身份认证和加密传输是两项不相关的安全配置,在Kafka/MSK上,身份认证和加密传输是有一些耦合关系的,重点是:对于MSK来说,当启用IAM, SASL/SCRAM以及TLS三种认证方式时,TLS加密传输是必须的&…

Ubuntu开机自启动设置

一、创建执行脚本 这里有两个程序所以编写了两个脚本,第一脚本(master.sh): gnome-terminal -- bash -c "source /home/zyy/anaconda3/bin/activate wood2;cd /home/zyy/pycharmProject/master_program;python main.py > /home/zyy/pycharmProj…

用于语义图像分割的弱监督和半监督学习:弱监督期望最大化方法

这时一篇2015年的论文,但是他却是最早提出在语义分割中使用弱监督和半监督的方法,SAM的火爆证明了弱监督和半监督的学习方法也可以用在分割上。 这篇论文只有图像级标签或边界框标签作为弱/半监督学习的输入。使用期望最大化(EM)方法,用于弱…

JavaScript--修改 HTML 元素

这些是一些用于修改 HTML 元素的常见方法&#xff1a; 1、document.createElement(element)&#xff1a;创建 HTML 元素节点。可以使用这个方法创建一个新的 HTML 元素&#xff0c; 例如 document.createElement(div) 将创建一个 <div> 元素节点。 2、document.createA…

elementUI 非表单格式的校验

在普通表单中对输入框、选择框都有校验案例。 但是在自定义非空中如何进行校验官网并没有说明 关键代码 clearValidate 方法清除校验 this.$refs.formValue.clearValidate(signinimg) 使用案例 <template><div class"stylebg"><Tabs icons"el-…

go mod 设置国内源 windows 环境 win10

启用 go module 功能 go env -w GO111MODULEon 配置 goproxy 变量 go env -w GOPROXYhttps://goproxy.cn,direct 下载包就行了&#xff0c;速度飞快 go mod tidy 检测 goproxy 是否配置好 运行 go env | findstr goproxy 查看 goproxy Go module 从 Go v1.12 版本开始存在&a…

flutter开发实战-底部bottomNavigationBar➕PageView

flutter开发实战-底部bottomNavigationBar tabbar在app中非常常见&#xff0c;底部BottomNavigationBar属性 一、BottomNavigationBar属性 BottomNavigationBar组件的常用属性&#xff1a; type&#xff1a;tabbar样式&#xff0c;默认为白色不显示&#xff1b;fixedColor:t…

S3C2440使用GPIO输入功能控制按键

文章目录 前言一、设置GPIO输入模式二、检测开关1.配置功能2.具体实现 总结 前言 由于上期分享的使用GPIO去控制引脚输出模式点亮LED&#xff0c;那么本期主要介绍一下使用GPIO设置为输入模式&#xff0c;用到的硬件有板载的按键&#xff1b;开发环境也是依赖于S3C2440开发板&…

TCP/IP网络编程 第十五章:套接字和标准I/O

标准I/O函数的优点 标准I/O函数的两个优点 将标准I/O函数用于数据通信并非难事。但仅掌握函数使用方法并没有太大意义&#xff0c;至少应该 了解这些函数具有的优点。下面列出的是标准I/O函数的两大优点: □标准I/O函数具有良好的移植性(Portability) □标准I/O函数可以利用缓…

【AI底层逻辑】——篇章3(下):信息交换信息加密解密信息中的噪声

续&#xff1a;【AI底层逻辑】——篇章3&#xff08;上&#xff09;&#xff1a;数据、信息与知识&香农信息论&信息熵 目录 三、信息是如何交换的 1、互联网与信息交换 2、哈夫曼和有效编码 四、信息的加密与解密 1、密码学的发展 2、可以被公开的密钥 五、信息…

python selenium.webdriver 爬取政策文件

文章目录 获取文章链接批量爬取政策文件应用selenium爬取文件信息数据处理导出为excel 获取文章链接 获取中央人民政府网站链接&#xff0c;进入国务院政策文件库&#xff0c;分为国务院文件和部门文件&#xff08;发改委、工信部、交通运输部、市场监督局、商务部等&#xff…

2023网络安全常见面试题汇总(附答案解析+配套资料)

以下为网络安全各个方向涉及的面试题&#xff0c;星数越多代表问题出现的几率越大&#xff0c;祝各位都能找到满意的工作。 注&#xff1a;所有的资料都整理成了PDF&#xff0c;面试题和答案将会持续更新&#xff0c;因为无论如何也不可能覆盖所有的面试题。 目录 一、渗透测试…

【Python】PyCharm中调用另一个文件的函数或类

&#x1f389;欢迎来到Python专栏~PyCharm中调用另一个文件的函数或类 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;Python学习专栏 文章作者技术和水平有限&#xff0c;如果文中出现错误&…

数据分析案例-数据分析师岗位招聘信息可视化

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

LLM - Hugging Face 工程 BERT base model (uncased) 配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131400428 BERT是一个在大量英文数据上以自监督的方式预训练的变换器模型。这意味着它只是在原始文本上进行预训练&#xff0c;没有人以…

MySQL:聚合函数(全面详解)

聚合函数 前言一、聚合函数介绍1、AVG和SUM函数2、 MIN和MAX函数3、COUNT函数 二、GROUP BY1、基本使用2、使用多个列分组3、 GROUP BY中使用WITH ROLLUP 三、HAVING1、基本使用2、WHERE和HAVING的对比 四、 SELECT的执行过程1、查询的结构2、SELECT执行顺序3、SQL 的执行原理 …

积分图像、图像分割、Harris角点检测

目录 1、积分图像 2、图像分割--漫水填充 3、图像分割--分水岭法 4、Harris角点检测 1、积分图像 #include <iostream> #include <opencv2/opencv.hpp>using namespace cv; using namespace std;//积分图像 int test() {//创建一个1616全为1的矩阵,因为2561616M…