【计算机网络】5. 网络基础3之详解TCP,UDP(三次握手、四次挥手、TCP的可靠机制、滑动窗口机制、TCP流量控制、拥塞控制机制、TCP粘包问题)

1. UDP协议

传输层:负责端与端之间的传输(端:端口,端点)

1.1 udp协议的特性

udp协议的特性:无连接、不可靠、面向数据报
(1)无连接:UDP客户端给服务端发送消息的时候,不需要和服务端先建立连接,直接发送(客户端也不清楚服务端是否真正在线)
(2)不可靠:UDP并不会保证数据是可靠有序到达对端
(3)面向数据报:UDP数据不管是和应用层还是网络层,都是整条数据交付

1.2 udp协议报头字段

在这里插入图片描述
(1)16位源端口号:当前的udp数据从哪一个进程产生
(2)16位目的端口号:当前的udp数据去往哪一个进程
(3)16位udp长度:udp数据的最大传输数据大小

  1. udp协议报头 + udp负载数据(应用层递交给udp数据)
  2. 2^16 = 65536字节

常问问题:

  1. udp传输数据的最大大小是多大?
    2^16 = 65536字节
  2. 如果想要传输比65536字节还要大的数据应该如何做?
    在应用层对数据进行分片,将超过65536字节的数据包进行拆分,分别使用udp协议进行传输
  3. 怎样分别传输?
    标识:同一个udp数据报具有相同的标识
    标志位:标识当前分片的udp数据后面还有没有分片
    片偏移:标识当前分片在整个udp数据包当中的位置
    在这里插入图片描述

(4)16位udp校验和:校验数据在传输的过程当中是否失真
            失真了:udp协议就会将该udp数据报丢弃
            没有失真:当应用层调用recvfrom函数的时候,就会将udp数据给到应用层

1.3 udp缓冲区

(1)发送缓冲区:将应用层提交给传输层的数据打上udp报头后就提交给网络层继续传输
(2)接收缓冲区:去掉udp报头之后,将数据递交给应用层。udp并不保证数据的可靠以及有序。

1.4 udp常见的应用场景

(1)DNS:域名解析
(2)DHCP:动态主机分配协议,谁上网给谁分配ip
(3)同一个局域网内部可能使用UDP,因为网络稳定
(4)NFS:网络文件系统

2. TCP协议

2.1 tcp协议的特性

TCP协议:面向连接、可靠传输、面向字节流
(1)面向连接:双方在发送网络数据之前必须先建立连接,再进行发送
(2)可靠传输:保证数据是可靠并且有序的到达对端
(3)面向字节流:多次发送的数据在网络传输过程当中没有明显的数据边界。比如先发123,再发456,另一端收到的就是123456,它没有间隔。

2.2 三次握手

2.2.1 数据包名称,连接状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.2 包序管理

在这里插入图片描述

2.2.3 网络抓包

win:wireshark针对网卡进行抓包
Linux:tcpdump:可以抓任意协议的数据包,并不是只能抓tcp
            命令范式:tcpdump -i any port [端口] -s 0 -w [命名的文件]
            port [端口]:是可选项,如果不加做则没有使用端口进行过滤,则抓取出来的数据包会比较大
            命名的文件:例如123.dat
            将抓出来的文件通过wireshark进行分析
注意:想要看到三次握手的过程,需要先开启抓包,再启动程序。

2.3 四次挥手

在这里插入图片描述

2.3.1 TIME_WAIT状态,MSL

只有“主动断开连接方”才会存在TIME_WAIT状态
MSL:报文最大生存时间
           自发送方发送出去之后,发送方认为该报文的最大生存时间是MSL
在这里插入图片描述
2MSL:ACK数据的MSL+被动断开连接方重传的FIN报文
重传的情况:(1)FIN报文还未到达被动断开连接方就丢失了
                      (2)主动断开连接方回复的ACK报文丢失
如果等待了2MSL的时间,也没有等到重传的FIN报文,则说明ACK数据一定到达了被动断开连接方

2.3.2 端口重用

服务端处于TIME_WAIT状态会引发什么样的问题?
在这里插入图片描述
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
listenfd:套接字描述符
SOL_SOCKET:套接字选项
SO_REUSEADDR:重用端口

2.3.3 CLOSE_WAIT状态

1.被动断开连接方才会存在的状态
2.处于CLOSE_WAIT状态的一方需要调用close函数关闭新连接的套接字。
被动断开连接方如果有大量的连接都处于CLOSE_WAIT状态,那需要检查代码中是否有阻塞,循环 导致被动断开连接方无法调用到close
在CLOSE_WAIT到LAST_ACK中,需要被动断开连接方调用close函数。

2.4 TCP协议段格式

在这里插入图片描述
(1)16位源端口号:当前的tcp数据从哪一个进程产生
(2)16位目的端口号:当前的tcp数据去往哪一个进程
(3)32位序号:用来标识tcp数据的起始序号
(4)32位确认序号:ack,告知对端,自己期望对端下一次发送数据的时候,从哪一个序号开始
(5)4位首部长度:最大为:1111 --》 15
         计算出来的是一个数值,并不是字节
         首部长度占用字节数量 = 4位首部长度计算出来的数值 * 4
         1111 --》 15 * 4 = 60字节
         tcp头部最大为60字节,最小为20字节
URG:紧急标志位(MSG_OOB:紧急数据,带外数据)
ACK:确认标志位
PSH:发送数据标志位
RST:重置连接标志位
SYN:发起连接标志位
FIN:断开连接标志位
(6)16位窗口大小:牵扯到滑动窗口机制
(7)16位校验和:判断TCP数据在传输过程中是否失真
(8)16位紧急指针:配置URG标志位一起使用,传输紧急数据
(9)选项:MSS:最大报文段长度

2.4.1 MSS

         MSS:最大报文段长度
                  TCP双方在三次握手过程中协商最大报文长度的大小
                  客户端 --》服务端:MSS_cli
                  服务端 --》客户端:MSS_svr
                  采用双方最小的MSS,作为后续传输数据的最大报文段长度,min(MSS_cli , MSS_svr)
         作用:
                  TCP在传输数据的时候,严格按照MSS进行传输
                  MSS的大小和本地的网卡息息相关
                  MSS + ipheader + tcpheader <= MTU
                  MSS一定是小于MTU
                  MTU:最大传输单元(数据链路层对网络数据的限制)
命令:ifconfig
在这里插入图片描述
TCP在每一次发送数据的时候,数据的大小都不会超过MSS
只有TCP有MSS的限制,UDP是没有的(unit16_t)!!!

2.5 TCP的可靠机制

2.5.1 确认应答机制

在这里插入图片描述

2.5.2 超时重传机制

当发送方发送了一个数据之后,就会开启一个重传计时器,当重传计时器记录的时间超过重传时间,则重传该报文
在这里插入图片描述
超时重传时间是固定的吗?
不是的
RTO:超时重传时间
RTT:报文往返时间
TRO:2 * RTT
RTT(预测本次数据包的报文往返时间)=RTT(prev)* 0.9 + RTT(prev)* 0.1
在这里插入图片描述

2.6 滑动窗口机制

2.6.1 什么是滑动窗口机制?

考虑到提高发送方发送的速率,接收方暂时不应答,允许发送方一次性发送多个分组到网络当中。

  1. 前提:TCP在确认应答机制和超时重传机制下,已经可以保证数据是可靠有序到达对端。但是如果单单只有该两个机制,就会导致TCP的发送方在发送下一个数据之前,会等待上一个数据的确认应答,这样整体的发送效率会比较低。
  2. 滑动窗口机制允许发送方一次性发送多个分组(每一个分组的大小不会超过MSS)到网络当中进行传输,但发送方接受到最早分组的确认应答之后,窗口可以向后滑动,包括下一个可以发送的分组。
  3. 滑动窗口机制提高了发送方和接收方的吞吐能力,提高了双方传输数据的效率

在这里插入图片描述
在这里插入图片描述
如果收到了后面分组的确认应答,但是没有收到前面分组的确认应答,则窗口不能向后滑动,防止前面分组在网络当中丢失掉了,需要进行重传。

2.6.2 滑动窗口机制如何控制双方的发送速率?

2.6.3 滑动窗口是如何进行变化的?(在TCP双方发送数据的时候,TCP发送方维护的窗口是一成不变的吗?)

滑动窗口:允许一次性丢到网络当中分组的集合,分组的个数就是窗口的大小
发送方窗口大小是动态变化的,取决于接收方通告的窗口大小

  1. TCP协议字段当中的"16位窗口大小":消息接收方告知消息发送方,消息接收方的接受能力的字段在这里插入图片描述
  2. (1)当TCP的接收方接受到数据之后,会将数据先缓存TCP的接受缓冲区当中
    (2)TCP的接收缓冲区的大小并不是无限制的大
    (3)一旦应用层不调用recv函数从接收缓冲区当中获取数据的时候,随着TCP接收缓冲区一直接收发送方发送的数据就会导致接收缓冲区的大小逐渐变小
    在这里插入图片描述
    这个窗口的大小是动态变化的。比如主机B接收能力是5000字节,当发送了4个窗口(4000个字节),响应还没有应答,那这时窗口的大小只能为1个(1000个字节),也不一定是一个,随着响应应答,也可能为2个,3个或者其他
    结论:接收方通过窗口大小,告知发送方自己的接收能力,接收方在接收数据的时候,会按照接收方通告的接收能力,动态的调整自己的发送数据的量(即窗口大小)

2.6.4 滑动窗口丢包

(1)丢失某个分组的ACK
在这里插入图片描述
当窗口当中某个分组的ACK丢失之后,可以通过收到的高确认序列号,来确认丢失ACK的分组数据都达到对端,从而不需要重传。
(2)丢失某个分组数据
在这里插入图片描述
如果数据丢失,一定要重传!!!

2.7 TCP流量控制,TCP流控制

TCP通过协议字段中的"窗口大小"字段来控制双方发送数据的数据量
如果对双方的发送数据的量不加以控制,则有可能导致接收方由于接收能力不足,而将发送方发送的数据丢弃掉,触发发送方进行重传,如此往复,网络当中就会充斥着大量的重传数据包,占用宽带资源。导致整个网络的转发能力变差。

2.7.1 0号窗口

在这里插入图片描述

2.7.2 什么时候恢复发送方给接收方发送数据,两种恢复方式

(1)发送方主动给接收方发送窗口探测包
询问接收方的接受能力,注意:窗口探测包的数据的大小为固定的1字节
(2)接收方主动给发送方发送窗口更新通知

2.8 拥塞控制机制

作用TCP的双方对发送数据的速率(提高了TCP的发送速率)
需要考虑的问题:一开始就要按照滑动窗口的大小,发送数据吗?
否,没有考虑到网络的转发能力是否能够满足一次性传输窗口大小的数据

  1. 网络传输的时候,数据是在"共享网络"当中进行传输的。换句话说,网络被多个网络收发双方所使用。同时在转发多个人的数据。
  2. 网络链路当中的路由器/交换机,换发能力是有上限的
  3. 网络链路当中的传输介质(光线/双绞线)是有传输上限的
    结论:TCP双方在发送数据的时候,为了不是网络原因,频繁的重传,则TCP双方在发送数据的时候,也是考量网络转发能力的。

拥塞控制机制:本质也是在控制发送方发送数据的量
最终发送的数据量:min(发送方的滑动窗口大小,拥塞控制机制当中的拥塞窗口大小)
发送方的滑动窗口大小取决于接收方的接收能力
拥塞控制机制当中的拥塞窗口大小取决于网络拥塞程度

2.8.1 慢启动

慢启动:TCP通信双方,在建立连接之后,先发送少量的数据(拥塞窗口的数据),探测网络的转发能力(根据TCP数据的往返时间),根据网络转发能力,主动调整拥塞窗口大小。
拥塞窗口的大小为1个分组(1个MSS)
在这里插入图片描述
在这里插入图片描述
慢启动:拥塞窗口的大小,随着传输轮次的增加,拥塞窗口呈现指数增长
慢开始门限:ssthresh的初始值
在拥塞窗口大小小于慢开始门限的时候,是呈指数增长
当拥塞窗口的大小超过慢开始门限,则转换位拥塞避免算法

2.8.2 拥塞避免

拥塞避免:随着传输轮次的增加,拥塞窗口的大小呈线性增长(一次增加1个分组)
(1)早期TCP发现网络拥塞之后,是将拥塞窗口调整为1(即1个分组),从慢开始重新增长拥塞窗口大小,重新调整慢开始门限。
在这里插入图片描述
(2)现在TCP的做法:快恢复。一旦发现网络阻塞,择机算新的慢开始门限,从新的慢开始门限执行拥塞避免算法。
在这里插入图片描述

2.8.3 快重传

快重传:当发送方发送的网络数据丢包之后,发送方还没有触发超时重传机制的时候,有接收方快速的确认丢失报文的起始序号,告知发送方该报文丢失,则发送方不需要等到超时之后才重传。
在这里插入图片描述
在这里插入图片描述

2.9 其他机制

2.9.1 延时发送机制

延时发送机制:NAGLE算法,如果当前发送方存在少量的数据需要发送,则稍微的等待一会,等待数据量变大之后,再统一进行发送。

2.9.2 捎带应答机制

捎带应答机制:应用于双方都想给对方发送数据的场景,快速的进行交互,就将ack放到PSH数据包当中携带给对方。

2.9.3 延时应答机制

延时应答机制:接收方接收到了数据,为了给消息发送方通告更大的窗口大小,等待一段时间,如果在这段时间内,应用层将数据从接收缓冲区当中接收走之后(recv函数),接收方在恢复确认的时候,就可以给发送方通告更大的窗口大小了。

2.9.4 TCP保活机制

心跳机制:判断空闲连接的双方是否是正常状态
在这里插入图片描述
在连接空闲的时候,就会启动一个保活计时器,记录连接空闲的时间,一旦当连接的空闲时间超过2小时,则主机B的TCP协议会主动给主机A发送保活探测包(心跳包)
如果主机B一直没有收到探测包的应答,则会每隔75秒发送一次,总共发送10次。
如果10次探测包都没有应答,则认为对端已经处于不正常的状态,则主动断开连接。
如果有应答,则认为连接正常。重新启动保活计时器进行计时。

2.10 TCP面向字节流

2.10.1 什么是面向字节流?

从发送数据的角度理解:应用层的应用程序在发送数据的时候,是调用send函数将应用层数据递交给传输层的TCP协议。递交给TCP协议之后,数据是暂时保存在发送缓冲区当中。
在这里插入图片描述
TCP发送数据一定是小于MSS,有自己发送数据的规律。
从接收的角度来思考:当数据到达接收方的接收缓冲区之后,接收方的应用程序调用recv函数可以接受任意字节。
面向字节流服务会导致数据之间没有明显的边界,会导致TCP粘包问题

2.10.2 TCP粘包问题

tcp服务端没有办法针对tcp数据进行拆分,拆分成不同的请求。比如发个12+12,24+24,可能收到12+1224+24,因为tcp是面向字节流的,数据之间并没有明显的间隔,就导致服务端无法拆分数据。
解决:
定义应用层自己的协议数据结构,来描述发送到数据
应用层头部+应用层数据+间隔符(\r\n)
每条数据都会由一个分隔符(\r\n),来间隔前后的两条数据

在这里插入图片描述
序列化:将对象转化成为二进制数据
反序列化:将二进制数据转化为对象
json是一种key/value的数据结构,可以支持嵌套定义,也可以支持多种基础类型(int,string,char),同同时也支持将json对象序列化成为二进制序列也可以将二进制反序列成为json对象

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值