计算机网络-TCP与UDP协议

image.png

背景

这篇文章的目的是为了彻底搞懂TCP/IP的一些相关内容,涉及三次握手、四次挥手、UDP和TCP的异同。

网络

计算机网络体系结构

本篇文章我们着重关注的就是运输层的TCP和UDP两种传输协议

第7层 应用层

应用层(Application Layer)提供为应用软件而设的接口,以设置与另一应用软件之间的通信。例如: HTTP,HTTPS,FTP,TELNET,SSH,SMTP,POP3等。

第6层 表达层

表达层(Presentation Layer)把数据转换为能与接收者的系统格式兼容并适合传输的格式。

第5层 会话层

会话层(Session Layer)负责在数据传输中设置和维护计算机网络中两台计算机之间的通信连接。

第4层 传输层

传输层(Transport Layer)把传输表头(TH)加至数据以形成数据包。传输表头包含了所使用的协议等发送信息。例如:传输控制协议(TCP、UDP)等。

第3层 网络层

网络层(Network Layer)决定数据的路径选择和转寄,将网络表头(NH)加至数据包,以形成分组。网络表头包含了网络数据。例如:互联网协议(IP)等。

第2层 数据链路层

数据链路层(Data Link Layer)负责网络寻址、错误侦测和改错。当表头和表尾被加至数据包时,会形成帧。数据链表头(DLH)是包含了物理地址和错误侦测及改错的方法。数据链表尾(DLT)是一串指示数据包末端的字符串。例如以太网、无线局域网(Wi-Fi)和通用分组无线服务(GPRS)等。
分为两个子层:逻辑链路控制(logic link control,LLC)子层和介质访问控制(media access control,MAC)子层。

第1层 物理层

物理层(Physical Layer)在局部局域网上传送数据帧(data frame),它负责管理计算机通信设备和网络媒体之间的互通。包括了针脚、电压、线缆规范、集线器、中继器、网卡、主机适配器等。

TCP

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议

尽管TCP和UDP都使用相同的网络层(IP),TCP却向应用层提供与UDP完全不同的服务。 TCP提供一种面向连接的、可靠的字节流服务。

TCP首部

TCP标头的控制位部分中有8位:

1
2
3
4
5
6
7
8
CWR:CWR 标志与后面的 ECE 标志都用于 IP 首部的 ECN 字段,ECE 标志为 1 时,则通知对方已将拥塞窗口缩小
ECE:若其值为 1 则会通知对方,从对方到这边的网络有阻塞。在收到数据包的 IP 首部中 ECN 为 1 时将 TCP 首部中的 ECE 设为 1.;
URG:该位设为 1,表示包中有需要紧急处理的数据,对于需要紧急处理的数据,与后面的紧急指针有关;
ACK:该位设为 1,确认应答的字段有效,TCP规定除了最初建立连接时的 SYN 包之外该位必须设为 1;
PSH:该位设为 1,表示需要将收到的数据立刻传给上层应用协议,若设为 0,则先将数据进行缓存;
RST:该位设为 1,表示 TCP 连接出现异常必须强制断开连接;
SYN:用于建立连接,该位设为 1,表示希望建立连接,并在其序列号的字段进行序列号初值设定;
FIN 发端完成发送任务,请求断开连接。

让我们假设我们想要观察用于建立TCP连接的数据包。回想一下,TCP在初始化新连接;TCP控制位的连接顺序为

1) 调用方发送SYN
2) 收件人用SYN、ACK响应
3) 呼叫方发送ACK

1
2
3
4
5
6
7
8
9
10
11
12
0                               15                              31
-----------------------------------------------------------------
| source port | destination port |
-----------------------------------------------------------------
| sequence number |
-----------------------------------------------------------------
| acknowledgment number |
-----------------------------------------------------------------
| HL | rsvd |C|E|U|A|P|R|S|F| window size |
-----------------------------------------------------------------
| TCP checksum | urgent pointer |
-----------------------------------------------------------------
  • source port : 源端口,占16位
  • destination port : 目的端口,占16位
  • sequence number : 序列号
  • acknowledgment number : 确认号
  • window size : 窗口大小
  • TCP checksum: TCP校验和是一个端到端的校验和,由发送端计算,然后由接收端验证。其目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动。如果接收方检测到校验和有差错,则TCP段会被直接丢弃。
  • urgent pointer : 应急指针
  • HL:数据偏移
  • rsvd:保留

TCP标头通常包含20个八位字节的数据,除非存在选项。图表的第一行包含八位字节0-3,第二行显示八位字节4-7等。从0开始计数,TCP控制位包含在八位字节13中:

1
2
3
4
5
0              7|             15|             23|               31
----------------|---------------|---------------|----------------
| HL | rsvd |C|E|U|A|P|R|S|F| window size |
----------------|---------------|---------------|----------------
| | 13th octet | | |

主要功能

  • 慢启动

    每当建立一个TCP连接时或一个TCP连接发生超时重传后,该连接便进入慢启动阶段。进入慢启动后,TCP实体将拥塞窗口的大小初始化为一个报文段,即:cwnd=1。此后,每收到一个报文段的确认(ACK),cwnd值加1,即拥塞窗口按指数增加。当cwnd值超过慢启动阐值(ssthresh)或发生报文段丢失重传时,慢启动阶段结束。前者进入拥塞避免阶段,后者重新进入慢启动阶段。

  • 拥塞避免

    在慢启阶段,当cwnd值超过慢启动阐值(ssthresh)后,慢启动过程结束,TCP连接进入拥塞避免阶段。在拥塞避免阶段,每一次发送的cwnd个报文段被完全确认后,才将cwnd值加1。在此阶段,cwnd值线性增加。

  • 快速重传

    快速重传是对超时重传的改进。当源端收到对同一个报文的三个重复确认时,就确定一个报文段已经丢失,因此立刻重传丢失的报文段,而不必等到重传定时器(RTO)超时。以此减少不必要的等待时间。

  • 快速恢复

    快速恢复是对丢失恢复机制的改进。在快速重传之后,不经过慢启动过程而直接进入拥塞避免阶段。每当快速重传后,置ssthresh=cwnd/2、ewnd=ssthresh+3。此后,每收到一个重复确认,将cwnd值加1,直至收到对丢失报文段和其后若干报文段的累积确认后,置cwnd=ssthresh,进入拥塞避免阶段。

TCP特点

TCP是一种面向广域网的通信协议,目的是在跨越多个网络通信时,为两个通信端点之间提供一条具有下列特点的通信方式:

(1)基于流的方式;
(2)面向连接;
(3)可靠通信方式;
(4)在网络状况不佳的时候尽量降低系统由于重传带来的带宽开销;
(5)通信连接维护是面向通信的两个端点的,而不考虑中间网段和节点。

为满足TCP协议的这些特点,TCP协议做了如下的规定:

①数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组;
②到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认;
③超时重发:发送方在发送分片时启动超时定时器,如果在定时器超时之后没有收到相应的确认,重发分片;
④滑动窗口:TCP连接每一方的接收缓冲空间大小都固定,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP在滑动窗口的基础上提供流量控制,防止较快主机致使较慢主机的缓冲区溢出;
⑤失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层;
⑥重复处理:作为IP数据报来传输的TCP分片会发生重复,TCP的接收端必须丢弃重复的数据;
⑦数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验和有差错,TCP将丢弃这个分片,并不确认收到此报文段导致对端超时并重发。

客户端 SYN 包超时重传的最大次数,是由 tcp_syn_retries 决定的,默认值是 5 次;
服务端 SYN、ACK 包时重传的最大次数,是由 tcp_synack_retries 决定的,默认值是 5 次。

三次握手

流程

  1. 客户端主动打开连接,发送同步请求(SYN=1,seq=随机数1),客户端由关闭状态进入同步发送状态。
  2. 服务端监听(接收)到同步请求,给客户端发送确认请求(SYN=1,ACK=1,seq=随机数2,ack=随机数1+1),服务端由监听状态进入同步收到状态。
  3. 客户端接收服务端确认请求,验证确认号后,正确再次给服务端发送确认请求(ACK=1,seq=随机数,ack=随机数2+1),客户端进入连接已建立,服务端接收到请求后验证后进入连接已建立状态。

案例

以一个百度搜索为案例进行抓包

1
2
3
4
5
[S] : SYN(开始连接)
[P] : PSH(推送数据)
[F] : FIN(结束连接)
[R] : RST(重置连接)
[.] : 没有 Flag 由于除了 SYN 包外所有的数据包都有ACK,所以一般这个标志也可表示 ACK

1.监听网络状态

1
sudo tcpdump host www.baidu.com

2.发送网络请求

1
curl www.baidu.com

3.查看日志详情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
17:17:34.338858 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [S], seq 1394712657, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 2857129435 ecr 0,sackOK,eol], length 0
17:17:34.350511 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [S.], seq 3244236479, ack 1394712658, win 8192, options [mss 1448,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0
17:17:34.350627 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [.], ack 1, win 4096, length 0
17:17:34.350726 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [P.], seq 1:78, ack 1, win 4096, length 77: HTTP: GET / HTTP/1.1
17:17:34.361486 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [.], ack 78, win 908, length 0
17:17:34.363093 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [.], seq 1:1441, ack 78, win 908, length 1440: HTTP: HTTP/1.1 200 OK
17:17:34.363101 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [P.], seq 1441:2782, ack 78, win 908, length 1341: HTTP
17:17:34.363173 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [.], ack 2782, win 4052, length 0
17:17:34.366279 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [F.], seq 78, ack 2782, win 4096, length 0
17:17:34.372105 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [P.], seq 1441:2782, ack 78, win 908, length 1341: HTTP
17:17:34.372179 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [F.], seq 78, ack 2782, win 4096, options [nop,nop,sack 1 {1441:2782}], length 0
17:17:34.377440 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [.], ack 79, win 908, length 0
17:17:34.381875 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [F.], seq 2782, ack 79, win 908, length 0
17:17:34.382039 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [.], ack 2783, win 4096, length 0
17:17:34.384873 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [.], ack 79, win 908, options [nop,nop,sack 1 {78:79}], length 0

4.日志内容详解

  • 第1行

    1
    17:17:34.338858 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [S], seq 1394712657, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 2857129435 ecr 0,sackOK,eol], length 0
  • 172.168.2.49.57578 > 14.215.177.38.http表示这个包的源IP为172.168.2.49,源端口为50869,“>”表示数据包传输方向,172.168.2.49.50869表示这个数据包的目的端IP为14.215.177.38,这里没有展示端口则目标端口缺省为80;

  • Flags是[S],表明是SYN建立连接包(即三次握手的第一次握手),seq 序号为1394712657,这个其实就是TCP三次握手的第一次握手:client(172.168.2.49)发送SYN请求建立连接包

  • win 65535: 表示当前窗口大小为65535字节

  • options [mss 1460,nop,wscale 6,nop,nop,TS val 4254789715 ecr 0,sackOK,eol] 为tcp首部可选字段mss 1460表示mss是发送端(客户端)通告的最大报文段长度,发送端将不接收超过这个长度的TCP报文段(这个值和MTU有一定关系)

  • nop是一个空操作选项

  • wscale指出发送端使用的窗口扩大因子为6

  • sackOK表示发送端支持并同意使用SACK

  • length 表示以太帧长度

  • 第6行

    1
    17:17:34.350511 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [S.], seq 3244236479, ack 1394712658, win 8192, options [mss 1448,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0
  • Flags是[S.],表明是SYN建立连接包(即三次握手的第二次握手,服务端向客户端发送响应),其中的.表示的就是ACK位为1(注意ACK位和ack是两个东西)

  • ack 其确认号为 1394712658,可以看到我们的ack其实就是上一次请求的 seq+1 得出的数

  • win 当前窗口大小为 8192

  • 第7行

    1
    17:17:34.350627 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [.], ack 1, win 4096, length 0
  • 三次握手的第二次握手,客户端向服务端发送ACK响应,当第三次握手后就可以发送数据

  • Flags [.] 表示 ACK=1

问题

  1. 为什么需要三次握手 ?因为最少三次才能确保双方都做好连接准备,第一次握手客户端是请求连接、第二次握手是服务端告知客户端已经准备好连接、第三次握手是客户端告知服务端也准备好连接。

四次挥手

流程

  1. 客户端主动发起结束连接请求,(FIN=1,seq=u),客户端进入终止等待1状态。
  2. 服务端接收到客户端的结束请求,返回其确认号(ACK=1 seq=v ack=u+1),告知客户端服务端接收到结束连接请求,服务端进入关闭等待状态。客户端进入终止等待2状态。
  3. 上层应用被动关闭,服务端发送完数据,再次向客户端发送结束连接确认请求,(FIN=1 ACK=1seq=w ack=u+1),服务端进入最后确认状态。
  4. 客户端接收到服务端结束确认请求,验证其正确性,向服务端发送最后确认(ACK=1 seq=u + 1 ack = w + 1),客户端进入时间等待状态,等待2MSL进入关闭状态,服务端接收到客户端确认请求,验证其正确性进入关闭状态。

案例

回到上方三次握手的案例

  • 第9行

    当前有客户端向服务器发送FIN标识位请求结束连接请求

1
2
3
4
5
6
7
17:17:34.366279 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [F.], seq 78, ack 2782, win 4096, length 0
17:17:34.372105 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [P.], seq 1441:2782, ack 78, win 908, length 1341: HTTP
17:17:34.372179 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [F.], seq 78, ack 2782, win 4096, options [nop,nop,sack 1 {1441:2782}], length 0
17:17:34.377440 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [.], ack 79, win 908, length 0
17:17:34.381875 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [F.], seq 2782, ack 79, win 908, length 0
17:17:34.382039 IP 172.168.2.49.57578 > 14.215.177.38.http: Flags [.], ack 2783, win 4096, length 0
17:17:34.384873 IP 14.215.177.38.http > 172.168.2.49.57578: Flags [.], ack 79, win 908, options [nop,nop,sack 1 {78:79}], length 0
  • Flags [F.] 当前结束连接请求,.表示确认号

问题

  1. 为什么需要四次挥手?因为为了保证等数据完成的被接收完再关闭连接。从上面的流程可以看出,客户端发送结束连接请求时,并非立即关闭连接,而是转而通知应用层,由应用层来确认数据是否已经发送完整,再通过应用层来被动关闭连接。

TCP的可靠性原理

超时重传

TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间 RTT。TCP 保留了RTT 的一个加权平均往返时间 RTTs(这又称为平滑的往返时间,S 表示 Smoothed。因为进行的是加权平均,因此得出的结果更加平滑)。每当第一次测量到 RTT 样木时,RTT值就取为所测量到的 RTT 样本值。但以后每测量到一个新的 RTT样本,就按下式重新计算一次RTTs

流量控制

tcp通过窗口滑动来控制流量

拥塞控制

image.png

1.慢启动:

定义拥塞窗口,由小到大逐渐增大发送窗口。(每次收到确认应答,窗口大小*2)

2.拥塞避免:

设置慢启动的阈值,当窗口大小达到阈值时,窗口数值不再*2,而是线性增加(每次确认,窗口大小+1)一旦发生超时重传,阈值设为当前窗口一半再重新进行慢启动过程

3.快重传:

M1接收确认,M2接收确认,M3没有接收到但是接收到了M4,必须立即发出对M2的重复确认,发送方一连收到3个重复确认立即进行重传,不会误认为网络拥塞。

4.快恢复:

将阈值和窗口大小都调整为现在门限的一半并开始执行拥塞避免算法。

UDP

用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。

image.png

主要功能

为了在给定的主机上能识别多个目的地址,同时允许多个应用程序在同一台主机上工作并能独立地进行数据包的发送和接收,设计用户数据报协议UDP。UDP使用底层的互联网协议来传送报文,同IP一样提供不可靠的无连接数据包传输服务。它不提供报文到达确认、排序、及流量控制等功能。UDP Helper可以实现对指定UDP端口广播报文的中继转发,即将指定UDP端口的广播报文转换为单播报文发送给指定的服务器,起到中继的作用。

主要特点

UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包而言UDP的额外开销很小。
吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

虽然UDP是一个不可靠的协议,但它是分发信息的一个理想协议。例如,在屏幕上报告股票市场、显示航空信息等等。UDP也用在路由信息协议RIP(Routing Information Protocol)中修改路由表。在这些应用场合下,如果有一个消息丢失,在几秒之后另一个新的消息就会替换它。UDP广泛用在多媒体应用中。

UDP首部

image.png

由于 IP层已经把IP数据报分配给TCP或UDP(根据I P首部中协议字段值),因此TCP端口号由TCP来查看,而UDP端口号由UDP来查看。TCP端口号与UDP端口号是相互独立的。
image.png

抓包案例

1.监听指定端口

1
sudo tcpdump udp port 90

2.抓取的日志

1
2
3
4
5
6
7
8
9
tcpdump: data link type PKTAP
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pktap, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
14:07:27.155813 IP 0.0.0.0.bootpc > broadcasthost.bootps: BOOTP/DHCP, Request from 38:37:8b:b0:f2:82 (oui Unknown), length 302
14:07:27.161219 IP 172.168.2.49.50971 > public1.alidns.com.domain: 42410+ PTR? 0.0.0.0.in-addr.arpa. (38)
14:07:27.169710 IP public1.alidns.com.domain > 172.168.2.49.50971: 42410 NXDomain* 0/1/0 (87)
14:07:27.173846 IP 172.168.2.49.51489 > public1.alidns.com.domain: 21914+ PTR? 255.255.255.255.in-addr.arpa. (46)
14:07:27.180977 IP public1.alidns.com.domain > 172.168.2.49.51489: 21914 NXDomain 0/1/0 (114)
14:07:27.184001 IP 172.168.2.49.59021 > public1.alidns.com.domain: 17052+ PTR? 49.2.168.172.in-addr.arpa. (43)

比较

\ 连接 服务对象 可靠性 拥塞控制、流量控制 首部开销 传输方式 分片不同
TCP TCP 是面向连接的传输层协议,
传输数据前先要建立连接。 TCP 是一对一的两点服务,
即一条连接只有两个端点。 TCP 是可靠交付数据的,
数据可以无差错、
不丢失、不重复、
按需到达。 TCP 有拥塞控制和流量控制机制,
保证数据传输的安全性。 TCP 首部长度较长,会有一定的开销,
首部在没有使用「选项」字段时是 20 个字节,
如果使用了「选项」字段则会变长的。 TCP 是流式传输,
没有边界,
但保证顺序和可靠。 TCP 的数据大小如果大于 MSS 大小,则会在传输层进行分片,目标主机收到后,也同样在传输层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
UDP UDP 是不需要连接,
即刻传输数据。 UDP 支持一对一、一对多、
多对多的交互通信 UDP 是尽最大努力交付,
不保证可靠交付数据。 UDP 则没有,即使网络非常拥堵了,
也不会影响 UDP 的发送速率。 UDP 首部只有 8 个字节,
并且是固定不变的,开销较小。 UDP 是一个包一个包的发送,
是有边界的,
但可能会丢包和乱序。 UDP 的数据大小如果大于 MTU 大小,则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完数据,接着再传给传输层,但是如果中途丢了一个分片,则就需要重传所有的数据包,这样传输效率非常差,所以通常 UDP 的报文应该小于 MTU。

U D P和TCP在首部中都有覆盖它们首部和数据的检验和。 UDP的检验和是可选的,而TCP 的检验和是必需的。

总结

图片来源:https://blog.csdn.net/yaopeng_2005/article/details/7064869

在浏览器输入网址回车后涉及哪些协议 ?

从 OSI 模型来层层递进说明

  1. 首先应用层上来讲,在我们输入网址后会预先解析其域名,此时用到应用层的DNS协议。
  2. 在DNS解析的过程中如果本地没有该域名缓存,则需要向DNS服务器进行查询,传输层此时用到UDP协议。
  3. 在获得域名IP后得到开始进行三次握手连接服务器,此时传输层用到TCP协议,应用层HTTP/HTTPS/SSL协议。
  4. 网络层使用到IP协议/OPSF协议。
  5. 数据链路层使用ARP协议将IP地址转为MAC地址。

为什么需要等待2MSL?

  1. 确保发送方发送的第四次挥手ACK报文可以到达接收方;
  2. 确保当前连接的所有报文都已经过期;

资料

TCP-IP详解(卷一、二、三).pdf

《图解HTTP》完整彩色版.pdf


计算机网络-TCP与UDP协议
https://mikeygithub.github.io/2020/03/09/yuque/计算机网络-TCP与UDP协议/
作者
Mikey
发布于
2020年3月9日
许可协议