背诵版TCP/UDP

TCP/UDP

  1. 传输控制协议-TCP:提供面向连接的,可靠的数据传输服务
  2. 用户数据协议-UDP:提供无连接的,尽最大努力交付的数据传输服务(不保证可靠传输)

TCP、UDP区别

UDPTCP
是否连接无连接面向连接
是否可靠不可靠,不使用流量控制和拥塞控制可靠有序,不丢不重,使用流量控制和拥塞控制
连接对象个数一对一、一对多、多对一、多对多一对一、全双工
传输方式面向报文面向字节流
首部开销8B(源端口号+目的端口号+UDP长度+校验和)20B
场景实时通信可靠传输场景,如文件传输

运行在TCP上的协议

  • HTTP(Hypertext Transfer Protocol,超文本传输协议),主要用于普通浏览。80
  • HTTPS(HTTP over SSL,安全超文本传输协议),HTTP协议的安全版本。443
  • FTP(File Transfer Protocol,文件传输协议),用于文件传输。21
  • POP3(Post Office Protocol, version 3,邮局协议),收邮件用。110
  • SMTP(Simple Mail Transfer Protocol,简单邮件传输协议),用来发送电子邮件。25
  • TELNET(Teletype over the Network,网络电传),通过一个终端(terminal)登陆到网络。23
  • SSH(Secure Shell,用于替代安全性差的TELNET),用于加密安全登陆用。22

运行在UDP上的协议

  • BOOTP(Boot Protocol,启动协议),应用于无盘设备。
  • NTP(Network Time Protocol,网络时间协议),用于网络同步。
  • DHCP(Dynamic Host Configuration Protocol,动态主机配置协议),动态配置IP地址。67,68

运行在TCP+UDP上的协议

  • DNS(Domain Name Service,域名服务),用于完成地址查找,邮件转发等工作。

TCP报文头部结构

img

  1. 源端口和目的端口: 各占2个字节,分别写入源端口号和目的端口号。

  2. 序号:seq序号(序列号),占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行 标记。用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。

  3. 确认序号:ack序号(确认号),占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。例如 B 正 确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号 为 701,B 发送给 A 的确认报文段中确认号就为 701。

  4. 标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:

    • ACK:确认序号有效。当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报 文段都必须把 ACK 置 1。
    • SYN:发起一个新连接。在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文 段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。
    • FIN:释放一个连接。用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要 求释放连接。
    • PSH:接收方应该尽快将这个报文交给应用层。
    • RST:重置连接。
    • URG:紧急指针(urgent pointer)有效。
  5. 窗口:窗值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。指明了现在允许对方发送的数据量,经常动态变化。

  6. 检验和:占2个字节;检验和字段检验的范围包括TCP首部、TCP数据、TCP 伪首部。12字节的伪首部(4-源IP,4-目的IP,1-0,1-协议号[6],2-报文长度)

TCP的三次握手四次挥手

三次握手

三次握手的本质是确认通信双方收发数据的能力。

在这里插入图片描述

原理
  • 第一次握手:建立连接是,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列号。
  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态。
  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
为什么要三次握手?

三次握手的最主要目的是「双方确认自己与对方的发送与接收是正常的」。

第一次握手:Client什么都不能确认;Server确认了:自己接受正常,对方发送正常。

第二次握手:Client确认了:自己发送、接收正常,对方发送、接收正常。

第三次握手:Server确认了:自己发送、对方接受正常。

所以三次握手就能确认双方收发功能是否正常。

三次握手为什么不用2次,或者4次?

因为只有三次才最合适,三次通信是最小值,两次通信无法确认双方收发功能的正常,而四次通信则显得有些冗余。

三次握手,第一次握手有没有数据?

没有,因为此时还没有建立服务端的连接。但是第三次握手时,可以携带数据。TCP标准规定,第三次握手的报文,可以携带数据,因为此时客户端已经处于established状态。

四次挥手

四次挥手的目的是关闭一个连接。

在这里插入图片描述

原理
  1. 第一次挥手:当客户端所有的数据传输完成后 (当然数据没发完时也可以发送连接释放报文并停止发送数据), 客户端向服务端发送一条 连接释放报文 ,包含 FIN=1 标志位,客户端停止发送数据,客户端进入 FIN-WAIT-1 状态 。

  2. 第二次挥手: 服务端收到客户端的连接释放报文后,向客户端发送一条 确认报文 ,包含 ACK=1 标志位,此时服务端进入 CLOSE-WAIT 状态 。表明服务端处于等待关闭状态,还没有给客户端发送FIN报文,等待数据传输完成。半关闭状态:A-B连接释放

  3. 第三次挥手: 服务端将最后的数据传输完成后,向客户端发送一条 连接释放报文 ,此时的报文中含有 FIN=1 标志位,服务器停止发送数据,此时服务器进入 LAST-ACK 状态 。表明自己(服务端)已经准备好关闭连接了,等待最后一次确认。

  4. 第四次挥手: 客户端收到服务端的连接释放报文后,再向服务端发送一条 确认报文 ,包含 ACK=1 标志位, 此时客户端进入 TIME-WAIT 状态 。注意客户端发出确认报文后不是立马释放TCP连接,而是要经过 2MSL (报文段最长生命周期的2倍时长)后才释放TCP连接。而服务端一旦收到客户端发出的确认报文就会立马释放TCP 连接,所以服务端结束TCP连接的时间要比客户端早一些。

    • 等待2MSL原因

      1) 为了保证A发送的最后一个ACK报文能够到达B

      2) 防止“已失效的连接请求报文段”出现在新的连接中。在该2MSL中,可以是本连接持续的时间内的所产生的所有报文段都从网络中小时,新的连接不会出现旧的连接请求报文段。

为什么TCP连接的时候是3次,关闭的时候却是4次?

全双工

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接是,当收到对方的FIN报文是,仅仅表示对方不再发送数据了,但是还能接收数据,已方也未必全部数据都发送给对方了,所以已方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,已方ACK和FIN一般都会分开发送。

常见问题

如果已经建立了连接,但是客户端突然出现故障了怎么办?

  • TCP设有一个保活计时器,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时。
  • 若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段**(,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客 户端出了故障,接着就关闭连接。

流量控制时,B向A发送零窗口报文段后,又有了存储空间,但非零窗口报文段丢失。

A此时等待B的非零窗口报文段的通知,B等待A发送数据,形成死锁。解决方法:

  • TCP设有一个持续计时器,接收到零窗口报文通知后就启动
  • 若设置时间到,就会发送一个零窗口探测报文段(仅携带1字节数据),对方给出现在的窗口值,打破死锁。若窗口值仍为0,则重新启动持续计时器

大量的TIME_WAIT状态TCP连接,对业务有什么影响?

  • TIME_WAIT 状态:
    • 1.TCP 连接中,主动关闭连接的一方出现的状态;(收到 FIN 命令,进入 TIME_WAIT 状态,并返回 ACK 命令)
    • 2.保持 2 个 MSL 时间,即,4 分钟;(MSL 为 2 分钟)
  • 影响
    • 每一个 time_wait 状态,都会占用一个「本地端口」,上限为 65535(16 bit,2 Byte);
    • 当大量的连接处于 time_wait 时,新建立 TCP 连接会出错,address already in use : connect 异常
  • 统计 TCP 连接的状态
// 统计:各种连接的数量 
$ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' ESTABLISHED 1154 
TIME_WAIT 1645
  • 大量的 TIME_WAIT 状态 TCP 连接存在,其本质原因:

    • 大量的短链接存在
    • 如果 connection 头部取值被设置为 close 时,基本都由「服务端」 发起主动关闭连接
    • 而 TCP 四次挥手关闭连接机制中,为了保证 ACK 重发和丢弃延迟数据,设置 time_wait 为 2 倍的 MSL(报文最大存活时间)
  • 解决方法:

    • 客户端 / 浏览器

      将 HTTP 请求的头部,connection 设置为 keep-alive,保持存活一段时间。

    • 服务器端

      允许 time_wait 状态的 socket 被重用

      缩减 time_wait 时间,设置为 1 MSL

TCP的可靠性是如何保证的?

  1. 校验和:CRC校验全部数据
  2. 序列号/确认应答:确保了数据是按序、完整到达
  3. 超时重传:保证因链路故障未能到达数据能够被多次重发
  4. 滑动窗口/流量控制:点对点提供流量控制,避免过量发送
  5. 拥塞控制:提供全局流量控制,避免过量发送

TCP粘包拆包

粘包拆包问题是处于⽹络⽐较底层的问题,在数据链路层、⽹络层以及传输层都有可能发⽣。我们⽇常的⽹络应⽤开发⼤多数都在传输层进⾏的。

由于UDP有消息保护边界,不会发生这个问题。

TCP是⾯向连接的,⾯向流的,提供⾼可靠性服务。由于TCP⽆消息保护边界,需要在接收端处理消息边界问题,也就是我们所说的粘包、拆包问题。

粘包拆包发生场景

因为TCP是面向传输的,没有边界,因此操作系统在发送TCP数据时,会通过缓冲区来进行优化

  1. 理想情况下,两个包恰好满足缓冲区的大小或达到TCP等待时长,分别发送两个包,服务端分两次读取到了两 个独立的数据包,没有粘包和拆包;
  2. 当两个包比较小时,发生粘包,合并成一个包发送,服务端一次接受到了两个数据包,称之为TCP粘包
  3. 一个包过大,超过缓存区大小,拆分成两个或多个包发送,服务端分多次才读取到一个完整的数据包,称之为 TCP拆包
  4. 也有可能一个包较大或较小,第一次读取到了完整的D1包和D2包的部分内容,第二次读取到了D2包的剩余内容,或者第一次读取到了D1包的部分内容D1_1,第二次读取到了D1包的剩余部分内容D1_2和完整的D2包,粘包和拆包一起发生
粘包拆包产生原因
  1. 应⽤程序写⼊的数据⼤于套接字缓冲区⼤⼩,这将会发⽣拆包问题。

  2. 应⽤程序写⼊的数据⼩于套接字缓冲区⼤⼩,⽹卡将应⽤多次写⼊的数据发送到⽹络上,这将会发⽣粘包问题。

  3. MSS(最⼤报⽂⻓度-TCP)/MTU(最大传输单元-数据链路层)限制⼤⼩的TCP分段

    • 当TCP报⽂⻓度-TCP头部⻓度>MSS的时候将发⽣拆包问题。

    • 当需要传输的数据大于MSS或者MTU时,数据会被拆分成多个包进行传输。

      由于MSS是根据MTU计算出来的,因此当发送的数据满足MSS时,必然满足MTU。

      MSS=MTU长度-IP Header-TCP Header

      TCP Header的长度是20字节,IPv4中IP Header长度是20字节,IPV6中IP Header长度是40字节,因此:在IPV4中, 以太网MSS可以达到1460byte;在IPV6中,以太网MSS可以达到1440byte。

  4. Nagle算法:

    Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。

    • 将发送数据放入TCP缓存
    • 发送第一个字节
    • 收到第一个ACK后,将缓存中的所有数据组装成一个报文段发出去
    • 收到前一个报文段的确认后,再发送下一个报文段

重传机制、滑动窗口、流量控制、拥塞控制

重传机制

超时重传、快速重传、SACK、D-SACK

超时重传

就是 在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据 ,也就是我们常说的超时重传。

TCP 会在以下两种情况发生超时重传:

  • 数据包丢失
  • 确认应答丢失
快速重传(Fast Retransmit)机制

拥塞控制时配合快恢复使用

它不以时间为驱动,而是以数据驱动重传。相当于超时重传是定时器,快速重传是计数器。

原理: 在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认 。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。在发送方,如果收到三个重复确认,那么可以知道下一个报文段 丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。 这就是快速重 传,也叫快重传。 所以,快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。

SACK

SACK( Selective Acknowledgment 选择性确认)

解决为按序到达,缺少部分data

在建立连接时,就双方确认“允许SACK”,以后所有的报文首部都增加SACK选项。

由于首部选项的长度只有40字节,最多只能指明四个字节块的边界信息(4个字节块8个边界32个字节,1字节指明SACK选项,1字节说明占用多少字节)

D-SACK

Duplicate SACK 又称 D-SACK ,其主要使用了 SACK 来告诉「发送方」有哪些数据被重复接收了。

相比于 SACK,D-SACK 有这么几个好处:

  1. 可以让「发送方」知道,是发出去的包丢了,还是接收方回应的 ACK 包丢了;
  2. 可以知道是不是「发送方」的数据包被网络延迟了;
  3. 可以知道网络中是不是把「发送方」的数据包给复制了;
滑动窗口(以字节为单位)

为了在流量控制时,控制发送方的发送速率,保证接收方来的及接受。

发送方和接受方各自维护一个窗口,通过TCP首部的窗口值来告知对方自己的窗口大小。

发送发窗口大小是动态变化的

发 送 窗 口 上 限 值 = M i n 接 收 方 窗 口 值 r w m d , 拥 塞 窗 口 c w n d 发送窗口上限值 = Min{接收方窗口值rwmd,拥塞窗口cwnd} =Minrwmdcwnd

1. 发送窗口
  • 发送应用程序传送给TCP准备发送的数据
  • 已发送但未收到确认的数据
2. 接受窗口
  • 按序到达,但尚未被应用程序读取
  • 未按序到达的数据
流量控制

如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。

流量控制是为了控制发送的发送速率以保证接收方来得及接收,通过滑动窗口机制实现

接收方发送确认报文的时候会将自己的窗口大小告知发送方,从而影响发送方的发送速率。将窗口字段设为 0,则发送方不能发送数据。

拥塞控制
1. 如何知道发生拥塞

当发生了超时重传,就认为网络发生了拥塞。[发送的报文没有收到ACK]

2.如何解决拥塞:慢开始&拥塞避免;快重传&快恢复

img

慢开始&拥塞避免

  • 慢开始

    发送最初执行慢开始,cwnd = 1,每收到一次确认,cwnd翻倍(2,4,8,…) 这里的数字指的是1个SMSS(发送方的最大报文段)

    发送方发送速度过快,使得网络拥塞可能性更高,设置一个慢开始门限ssthresh

  • 拥塞避免

    cwnd >ssthresh时,进入拥塞避免,每个轮次cwnd 只增加1

    如果发生超时,则ssthresh = cwnd / 2,cwnd = 1

快重传&快恢复

  • 快重传

    img

    在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。

    例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。 在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。 例如收到三个 M2,则 M3 丢失,立即重传 M3。

  • 快恢复

    img

    在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,

    ssthresh = cwnd/2 , cwnd = ssthresh,注意到此时直接进入拥塞避免,即每个轮次只将 cwnd 加1

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值