UDP协议
- 源IP,源端标语
- 目标IP,目标端标语
- UDP/TCP
- 一个历程是否可以绑定多个端标语? 可以。
- 多个历程是否可以绑定一个端标语? 不可以,由于端标语的主要作用是唯一标识一台盘算机上的一个特定服务或应用步伐,以便网络通信能够准确无误地发送到正确的吸收者。
UDP的格式
- 16位UDP长度:就是数据的大小
- 16位UDP检验和:用于检验报文的完备性
UDP怎样解包和分用?
- 解包:前八个字节是固定格式,然后根据UDP长度读取数据就可以了。
- 分用:有目标端标语,知道交付给上层的哪个历程。
UDP的缓冲区
- UDP有吸收缓冲区,但没有真正意义上的发送缓冲区–>由于UDP是无连接,不可靠的,面相数据报的,不必要保证发送成功,直接交付给下一层就可以
TCP协议
传输控制协议
- 应用层将数据拷贝给了OS,未来数据的发送都有OS控制
协议格式
- 4位首部长度:表示的是报头+选项的大小;根本单位是4字节,占4比特,能表示的大小为[0,15],表示的意思为4*[0,15] = [0,60];报头是固定的格式,大小为20字节,所以现实表示的大小为[20,60].
怎样解包和分用?
- 解包:固定格式,读取出报头,根据4位首部长度得到选项,剩下的就是数据了
- 分用:16位目标端标语
确认应答
- 保证TCP传输可靠性的方式之一。
- 怎样保证消息被对方收到?
收到应答
- 怎样保证应答被收到呢?
那就必要给对方应答,怎样保证自己的应答被收到呢?这就套娃了。
- 长距离的通信没有100%的可靠性,由于总有最新的一条消息没有应答。这句话的意思也就是说老消息是有应答的。
序号和确认序号
- 确认序号 = 序号+1;表示的意义是确认序号之前的内容都已经被全部收到。
- 序号的作用:
- 对报文进行区分,可以对报文进行去重
- 报文可能是乱序的,保证报文的顺序到达
根据上面的信息只必要一个序号就可以了,为什么要有两个序号?
捎带应答机制
- 假设客户端给服务器发送数据,此时服务器吸收到请求而且想要给服务器发送数据。此时如果有两个序号就可以用一个报文来完成应答和发送数据,否则就必要发送两次,应答用的是确认序号,发送数据用的是序号。
- TCP报文在很大概率上即是应答,又是数据。
16位窗口大小
- 16位窗口大小表示的是,接受缓冲区剩余空间大小。
- 万一对方来不及吸收?
抛弃吗?如果抛弃就必要重新发送一份,浪费时间。而且OS不做浪费时间和空间的事,所以不是抛弃,那么怎么办呢?
- 凭什么知道对方来不及吸收?
根据报文中的16为窗口大小,也就可以知道对方吸收缓冲区剩余空间大小来进行流量控制。
- 流量控制两边都要进行。
- 控制 != 淘汰;既可以是淘汰,也可以是增长。
面相字节省
- 缓冲区就是一个char outbuffer[N],也就是一个字符数组。
- 读写文件就是面相字节省的。
- 保证数据的完备性,必要对数据在应用层定协议,比如http。
超时重传机制
- 发送数据,在肯定的时间隔断内没有收到应答,那么就认为报文丢失,就必要对数据进行重传。
- 报文丢失分为两类:1.数据丢 2.应答丢
数据丢
应答丢
- OS怎样做到超时重传?
在系统方面,偶然钟中断等可以来实现。
时间隔断不能太长,不能太短,更不能固定。怎么设置的?
连接管理
创建连接:三次握手
- 以客户端发起创建连接的请求为例。
客户端向服务器发送创建连接的报文,服务器应答而且服务器向客户端发送创建连接的报文,最后就是客户端应答。
- 三次握手也可以是四次握手,只不外是有捎带应答机制,将应答和数据用了同一个报文。
断开连接:四次挥手
- 断开连接必要两边同意
- 客户端发送断开连接的报文,服务器应答;服务器发送断开连接的报文,客户端应答。
connect 和 accept
- connect只是触发三次握手;accept并不到场三次握手,只是等待三次握手的结束。
为什么要有三次握手和四次挥手?
- TCP是全双工的,必须保证两边通信的意愿,也就是必须两边同意。
- 以最小的代价来验证两边通信信道是通畅的。—>网络是通畅的。
- 四次挥手
TCP是全双工的,断开连接必要两边同意。
为什么要有标记位?
报文是由范例的,所以标记位用来区分报文的范例。
- ACK:应答报文,必要关心确认序号。
有捎带应答机制,所以大部分的TCP报文的ACK为1
- SYN:同步报文,创建连接
- FIN:断开连接
理解连接
- 一条连接和一个文件对应(也就是一个文件描述符fd)
- 在OS内有多个连接–>OS要对其进行管理(先描述,再构造)–>维护连接是有本钱的(时间+空间)
断开连接
- close是直接关闭读写端
- shutdown可以选择性关闭读端,写端或读写端
理解TIME_WAIT
- 主动发送断开连接的一方,发送最后一次挥手后,等待两个MSL(Maximum Segment Lifetime,报文段最大生存时间)时间。
- 为什么等待两个MSL?
1.等待历史的游离报文在网络中消散
2.确保ACK被对方收到
- 确保所有报文段都被处理:在TIME_WAIT状态下,TCP连接可以确保所有先前发送的报
- 文段都被对端正确接收和处理,包括最后的ACK报文段。
- 允许延迟的重复报文段被丢弃:如果网络中存在延迟的重复报文段(例如,由于网络拥塞
- 或路由问题),这些报文段可能会在连接关闭后到达。通过等待两个MSL时间,TIME_WAIT
- 状态可以确保这些延迟的报文段被丢弃,而不是被错误地处理为新的连接的一部分。
复制代码
- TIME_WAIT时,bind失败。
为什么? 连接关闭了吗?没关闭,端口正在被利用–>端口冲突
解决办法(这个标题在HTTP时遇到过,现在讲的是原理)
- setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR,&reuse, sizeof(reuse));
-
复制代码
流量控制
- 怎样实现?
通过16为窗口大小,告知对方自己吸收缓冲区的剩余空间大小(禁绝确)
- 16 位数字最大表示 65535, 那么 TCP 窗口最大就是 65535 字节么?
现实上, TCP 首部 40 字节选项中还包罗了一个窗口扩大因子 M, 现实窗口大小是 窗口字段的值左移 M 位
窗口探测和窗口更新
- 如果吸收缓冲区为0,怎么办?
通过窗口探测和窗口更新,来相识对方缓冲区是否有剩余空间
- 窗口探测就是一个裸的TCP报头
- 首次发送怎样知道对方的吸收能力?
三次握手是做过报文互换和窗口协商的,所以知道对方的吸收能力。
滑动窗口
- 进一步理解滑动窗口
滑动窗口只必要用start和end控制就可以了
滑动窗口的大小 = 对方吸收窗口的大小 (禁绝确)
- 串行发送,服从低
- 一次发多条数据(其实是将多个段的等待时间重叠在一起了)
- 为什么不能直接将这些数据当成一个大报文发送呢?而是一段一段呢?
数据链路层不允许发送大的报文。
标题
- 怎样滑动?start,end+移动加法
start = 确认序号
end = start + 对方窗口大小
确认序号,对方窗口大小都可以从对方发来的报文的报头中获取。
流量控制是怎样实现的? 通过滑动窗口
- 只能向右移动,能向左移动吗?
不能向左移动,由于左面的数据都是已发送的数据。
- 滑动窗口可以变大,变小,稳固,为0吗?
可以
- 超过发送缓冲区,会导致越界吗?
可以将发送缓冲区当成一个环形数组。
- 异常丢包标题
- 滑动窗口的最左侧丢包
最左侧丢包滑动窗口不会移动。
- 滑动窗口的中间丢包
滑动窗口右移,就酿成了最左侧丢包标题
- 滑动窗口的最右侧丢包
滑动窗口右移,就酿成了最左侧丢包标题
- 本质都是最左侧丢包标题。
快重传
- 数据到达,但应答丢包,部分 ACK 丢了并没关系, 由于可以通事后续的 ACK 进行确认;
- 数据丢包
- 收到三次重复简直认应答,就会对数据进行补发。
- 为什么还要有超时重传?
如果发送的报文数少于三个或每次的最后几个报文不能利用快重传,超时重传是用来兜底的,快重传提高了服从。
PSH和RST
- 对方吸收缓冲区剩余空间大小为0,而且也迟迟不将缓冲区中的数据交付给上层
PSH(push):告诉对方,请尽量将缓冲区的数据交给层—>侧面告诉OS数据很重要,请尽快交付
- RST(reset):链接重置
这是由于服务器没有与客户端创建连接,服务器知道创建连接错误了,所以就会向客户端发起带有RST为1的报文,重新进行三次握手创建连接。
- URG:紧急报文
情景:TCP是有序的,一些必要紧急处理惩罚的信息怎么办?
16位紧急指针:偏移量(紧急数据的位置),那么数据的大小呢?数据就是固定的1字节
- 识别并处理惩罚
- 总结以上的话题都是就端对端来讲的,以下的部分是网络方面
拥塞控制
- 大量数据包丢失–>判定当前网络拥塞–>全局层面,不止你网络拥塞,各人都网络拥塞。
- 解决办法:重传?不可以,各人都重传,那么只会加剧网络拥塞。
慢启动
拥塞窗口
- 拥塞窗口也可以控制发送的数据量。
- 发送数据量不是由滑动窗口控制吗?
发送的数据量由对方的吸收能力和网络共同决定。
滑动窗口 = min(对端缓冲区剩余空间大小,拥塞窗口大小)
- 为什么是指数增长?
前期慢,但增长快(尽快让网络通信规复)。
- 慢启动阈值 = 前次拥塞窗口大小/2
- 在阈值之后,拥塞窗口的大小是加法增大。
- 拥塞窗口为什么要不停增大?
评估网络健康情况,网络健康,拥塞等情况是不停变化的,所以必要不停增大,来评估网络的情况。
耽误应答
- 策略:
数量限定: 每隔 N 个包就应答一次;
时间限定: 超过最大耽误时间就应答一次;
- 三次握手,互换两边窗口的起始序号–>支持随机—>如许就可以肯定程度上防止游离报文
粘包标题
- TCP是基于字节省的,读取应用层报文时,没有读取到完备的报文。
- 解决办法: 在应用层明确报文的边界
TCP异常
- 历程终止:文件(sockfd)生命周期随历程,会在历程终止前释放文件描述符,两边进行四次挥手
- 机器重启:重启前,关闭所有的启动的历程,之后和历程终止一样。
- 掉电/掉网: 吸收端认为连接还在, 一旦吸收端有写入操纵, 吸收端发现连接已
经不在了, 就会进行 reset. 纵然没有写入操纵, TCP 自己也内置了一个保活定时器, 会定期询问对方是否还在. 如果对方不在, 也会把连接释放.
别的, 应用层的某些协议, 也有一些如许的检测机制. 例如 HTTP 长连接中, 也会定期检测对方的状态. 例如 QQ, 在 QQ 断线之后, 也会定期尝试重新连接.
连接保活
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |