您的位置:首页 > 文旅 > 旅游 > 公司设计网站多少钱_唐山做网站多少钱_整合营销的概念_无代码网站开发平台

公司设计网站多少钱_唐山做网站多少钱_整合营销的概念_无代码网站开发平台

2024/12/27 7:17:48 来源:https://blog.csdn.net/qhy850716/article/details/142390271  浏览:    关键词:公司设计网站多少钱_唐山做网站多少钱_整合营销的概念_无代码网站开发平台
公司设计网站多少钱_唐山做网站多少钱_整合营销的概念_无代码网站开发平台

一、TCP协议格式

我们看到报头固定有20字节,最后选项大小不固定。

4位首部长度(二进制0000 ~ 1111,十进制范围[0, 15])单位是4字节(存放字节大小范围[0, 60])包括了20字节固定长度 +选项长度。若选项大小为0,四位首部长度是5,即0101,用于解包。

二、TCP各种机制

1、确认应答机制

保证双方请求发送可靠性。

发送方和接收方不一定就是 client 和 server ,身份可以互换,上图举例。

只要 client 收到应答,就能保证上次 client 发送的请求 server 一定接收到了,这是保证了从 client 到 server 的数据发送可靠性。但是我们不能对应答再次应答来保证从 server 到 client 数据发送的可靠性,因为这样会死循环,所以一般不对应答进行处理。

可靠性:不是TCP协议保证每一个请求都能让发送方收到应答,而是能确认接收方是否得到了请求,如果得到发送方收到应答,没有就是发送方没收到应答。

TCP通信模式

首先由于应用层会有发送缓冲区和接收缓冲区来进行通信,Linux中把缓冲区以字节为单位逻辑上看成是数组,数字就是数组的下标,序号与确认序号就是这样的缓冲区中的数组下标。

2、超时重传机制

由确认应答机制可以知道,我收到了 ACK 就说明对方一定收到了数据,经过一段时间我没有收到 ACK,TCP协议规定我认为对方没有收到数据,我要补发数据。

没有收到 ACK 两种情况:

那么经过多长时间进行数据补发呢?与网络相关,Linux 中第一次超时0.5s,第二次超时1s,第三次超时2s,第一次超时4s...重复一定次数还没有收到就关闭不传了。

3、连接管理机制

正常情况下,三次握手建立连接,四次挥手断开连接。

(1)三次握手建立连接

标记位 SYN 表示申请建立连接

标记为 RST 表示要再次建立连接

我们看到最后一次服务器没有对 ACK 进行应答,实际上就算连接在最后一步出现问题,导致没有连接成功,客户端在发起 ACK 之后就认为连接已经建立,此时对服务器发送请求时,服务器发现没有连接成功就会返回 RST,客户端看到后就知道没有建立连接,重新三次握手建立连接。

(2)四次挥手断开连接

第一次挥手表示客户端向服务器发送的数据已经发完,之后客户端不会主动发消息给服务器,但由于没有第二次挥手,服务器还可以继续给客户端发消息,客户端也必须 ACK 应答,但应用层已经关闭,只能发 ACK 应答报头。

所以允许客户端还要收到服务器的消息就只能关闭套接字的写端。

用函数 int shutdown(int sockfd, int how) how中的选项 SHUT_WR 关闭写端。

(3)建立连接为什么要三次握手?

网络中有许多连接,为了管理连接就要先描述再组织,连接就是一个结构体,既要有空间存储,也要有时间来进行属性更新。所以三次握手也是在维护双方的连接结构体。

而且三次握手要有三次才能建立连接,对抗 SYN 洪水效果好。

原因:

a、验证全双工:即保证双方网络连通性,用最小的次数验证。

b、建立双方通信共识:客户端发送 SYN 说明客户端想连接服务器,服务器也发 SYN 说明服务器想连接客户端。

c、协商双方接受能力,在 ACK 应答报头中会带有16位窗口大小,这就是说当前接受缓冲区剩余量,用于为下一次数据发送进行发送量的确定。

(4)四次挥手中状态含义

服务器 CLOSE_WAIT 状态:客户端已经退出,服务器知晓,但是还不能立即关闭自己的 connfd

客户端 TIME_WAIT 状态:TCP规定,处于 TIME_WAIT 状态下在 2 * MSL(maximum segment lifetime 报文最大生存时间) 时间内不能再次监听同一个端口。

主动断开连接的一方最终会进入 TIME_WAIT 状态。

那如何不用等就可以重新监听端口呢?

int setsockopt(int sockfd, int level, int optname, void* optval, socklen_t* optlen)

level:所在层,SOL_SOCKET

optname:选项名字,SO_REUSEADDR,重新使用地址

optval:选项值,int opt = 1

optlen:选项大小,sizeof opt

函数作用是允许创建端口号相同,但IP地址不同的 socket 描述符,不用等就可以连接相同端口。

为什么要等 2MSL 时间,要有 TIME_WAIT ?

a、保证两个朝向尚未接受或迟到的报文在 2MSL 时间内被接受后丢弃(因为已经是超时报文)如果没有 TIME_WAIT,立即建立相同的连接,就会接收到之前的旧数据,导致数据错误。

b、同时也保证四次挥手最后的 ACK 服务器能就收到,要是没有 TIME_WAIT,客户端立即退出,ACK 传递出错,服务器再次向客户端发送 FIN 时客户端退出就会导致错误。

(5)连接管理总流程

4、流量控制

发送方会根据接收方的接收缓冲区剩余空间来动态调整发送速度。

所以接收方可以在 ACK 应答中的16窗口大小填写缓冲区剩余量来告知发送方。

窗口探测:主机A给主机B发空报头,B必须 ACK 应答带上窗口大小,主机A就能了解情况。

窗口更新通知:主机B终于能有空间接收请求时,会给主机A发消息,提醒他可以发数据了。

标记位 URG:紧急指针标记位(0无效,1有效)数据中有紧急数据,16位紧急指针就会标识紧急数据在数据中的偏移量。因为TCP协议中紧急数据大小1字节,所以只有偏移量没有大小。举例:0代表正常,1代表暂停,2代表取消...读取紧急数据知晓方法对应上层对于数据的处理方法。

recv 和 send 函数里面的 flag 标记设成 MSG_OOB 就可以对紧急数据设置

5、滑动窗口

问题

流量控制:具体怎么控制发送数据大小?

超时重传:超时时间内,已发送的数据不能丢弃,保存在哪里?

发送方规定了一个滑动窗口,在窗口内的数据可以直接发送,暂时不用收到应答。

根据感性的理解,滑动窗口是可以变大变小变成0,只能向右移。

构建模型:

缓冲区在Linux里面逻辑上看成是字节为单位的数组,则滑动窗口就是用双指针(win_start , win_end)维护的内存空间。

接收到 ACK 应答之后,win_start = 确认序号,win_end = win_start + 16位窗口大小。

考虑一个问题:如果数据丢包,滑动窗口如何移动?

建立模型


1、最左侧报文丢失

即2000的报文丢失,此时传来的 ACK 确认序号只能是1001,由于我们一次发送多条数据,应答回来的都是1001,超过3次重复应答,发送方就会意识到1001~2000的报文已经丢失,再次补发,下一次 ACK 确认序号就直接是5001,这就是快重传机制。

上述情况是报文丢了,但如果应答丢了呢?没关系,只要相信最新一次应答的确认序号就能确定下一次报文从哪里开始发送(由确认序号定义得知)

所以最左侧报文丢失移动策略:
a、由于确认序号规定的约束,滑动窗口左边界不动。

b、快重传和超时重传对左侧报文补发。

快重传 vs 超时重传

快重传要连续3次相同确认序号才能触发(保证效率),但是在极端情况下超时重传一定能识别到报文丢失(保证安全)

2、中间报文丢失

a、win_start = 确认序号,此时新滑动窗口就是最左侧报文丢失

b、由于确认序号规定的约束,滑动窗口左边界不动。

c、快重传和超时重传对左侧报文补发。

3、最右侧报文丢失

a、win_start = 确认序号,此时新滑动窗口就是最左侧报文丢失

b、由于确认序号规定的约束,滑动窗口左边界不动。

c、快重传和超时重传对左侧报文补发。

所以最后我们来回答最开始的两个问题。

流量控制:具体怎么控制发送数据大小?滑动窗口机制

超时重传:超时时间内,已发送的数据不能丢弃,保存在哪里?滑动窗口里面,出问题转化成最左侧报文丢失问题即可解决。

6、拥塞控制

(1)介绍网络拥塞

由于网络拥堵导致发送报文大面积的丢包,TCP会采用慢启动机制,先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据。

TCP解决网络拥塞的问题,最大的价值在于:在多个使用同一网络进行通信的主机有拥塞避免的共识。即TCP协议是全体主机都要遵守的,在网络拥塞的情况下,不能只从一台主机考虑,全体主机都必须减少报文发送才能缓解网络拥塞。

具体的拥塞控制:发送方的滑动窗口 = min(接收方的应答窗口,拥塞窗口)

(2)拥塞窗口

网络状况是浮动的,就说明拥塞窗口的大小肯定也是动态变化的。所以要经过多轮尝试才能得出准确的拥塞窗口大小。

慢启动机制

但是如果只是单纯向上面一样指数级增长就会导致测出来的拥塞窗口不准确,所以慢启动之后我们要让拥塞窗口线性增长来保证准确。

加法增大:达到阈值之后只能线性增长来探测到准确的网络拥塞值。

乘法减少:上一次的网络拥塞值的一半就是下一次慢启动的阈值。

但是不会无限线性增大下去,一定会有拥塞窗口极限值限制线性增长。

7、延迟应答

收到一批报文之后不会立即应答,等上层处理完一些请求之后能空出更多的接收窗口了,再 ACK 应答告知对方有更大的接收窗口,可以在网络不拥堵时保证传输效率。

但是延迟应答也有限制。

数量限制 : 每隔 N 个包就应答一次。
时间限制 : 超过最大延迟时间就应答一次。
具体的数量和超时时间 , 依操作系统不同也有差异。   一般 N 2, 超时时间取 200ms。

8、捎带应答

发送数据时带上上一次的应答数据

三、理解TCP面向字节流

创建一个 TCP socket, 同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区。
流程:
调用 write , 数据会先写入发送缓冲区中。
如果发送的字节数太长, 会被拆分成多个 TCP 的数据包发出。
如果发送的字节数太短, 就会先在缓冲区里等待 , 等到缓冲区长度差不多了 , 或者其他合适的时机发送出去。
接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区 ;
然后应用程序可以调用 read 从接收缓冲区拿数据。
全双工: TCP 的一个连接 , 既有发送缓冲区 , 也有接收缓冲区 , 那么对于这一个连接, 既可以读数据 , 也可以写数据。
面向字节流特点:
由于缓冲区的存在, TCP 程序的读和写不需要一一匹配
例如: 写 100 个字节数据时, 可以调用一次 write 100 个字节 , 也可以调用 100 次write, 每次写一个字节。读 100 个字节数据时 , 也完全不需要考虑写的时候是怎么写的 , 既可以一次
read 100 个字节 , 也可以一次 read 一个字节 , 重复 100 次。

四、TCP粘包问题

1、介绍粘包问题

首先要明确 , 粘包问题中的 " " , 是指的应用层的数据包。
在 TCP 的协议头中 , 没有如同 UDP 一样的 " 报文长度 " 这样的字段 , 但是有一个序号这样的字段。 序号只保证数据到应用层的有序性。
站在传输层的角度, TCP 是一个一个报文过来的。   按照序号排好序放在缓冲区中。
站在应用层的角度, 看到的只是一串连续的字节数据。
那么应用程序看到了这么一连串的字节数据, 就不知道从哪个部分开始到哪个部分, 是一个完整的应用层数据包。

2、解决粘包问题

(1)对于定长的包 , 保证每次都按固定大小读取即可。 例如上面的 Request 结构 , 是固定大小的, 那么就从缓冲区从头开始按 sizeof(Request) 依次读取即可。
(2)对于变长的包, 可以在包头的位置 , 约定一个包总长度的字段 , 从而就知道了包的结束位置。
(3)对于变长的包, 还可以在包和包之间使用明确的分隔符 ( 应用层协议 , 是程序员自己来定的, 只要保证分隔符不和正文冲突即可)

3、UDP不用考虑粘包问题

对于 UDP, 如果还没有上层交付数据 , UDP 的报文长度仍然在 . 同时 , UDP 是一个一个把数据交付给应用层. 就有很明确的数据边界。
站在应用层的站在应用层的角度, 使用 UDP 的时候 , 要么收到完整的 UDP 报文, 要么不收 . 不会出现 " 半个 " 的情况。面向数据报。

五、TCP异常

进程终止 : 进程终止会释放文件描述符 , 仍然可以发送 FIN,依然可以四次挥手
机器重启 : 和进程终止的情况相同。
机器掉电 / 网线断开 : 接收端认为连接还在 , 一旦接收端有写入操作 , 接收端发现连接已经不在了, 就会进行 reset. 即使没有写入操作 , TCP 自己也内置了一个保活定时器 , 会定期询问对方是否还在. 如果对方不在 , 也会把连接释放。
另外, 应用层的某些协议, 也有一些这样的检测机制. 例如 HTTP 长连接中, 也会定期检测对方的状态. 例如 QQ, 在 QQ 断线之后, 也会定期尝试重新连接.

六、TCP小结

可靠性: 校验和,序列号(按序到达) ,确认应答机制,超时重传机制,连接管理机制,流量控制机制,拥塞控制机制

提高性能: 滑动窗口,快速重传机制, 延迟应答机制,捎带应答机制

七、TCP / UDP对比

我们说了 TCP 是可靠连接 , 那么是不是 TCP 一定就优于 UDP ? TCP UDP 之间的优点和缺点, 不能简单 , 绝对的进行比较。
TCP 用于可靠传输的情况 , 应用于文件传输 , 重要状态更新等场景。
UDP 用于对高速传输和实时性要求较高的通信领域 , 例如 , 早期的 QQ, 视频传输等. 另外 UDP 可以用于广播。
归根结底 , TCP UDP 都是程序员的工具 , 什么时机用 , 具体怎么用 , 还是要根据具体的需求场景去判定。

八、用UDP实现可靠性传输

1、引入超时重传机制,防止丢包

2、引入确认应答机制,保证对方收到数据

3、引入序号,保证数据接收顺序

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com