IP、TCP、HTTP(一)

本文主要详解TCP三次握手都做了什么,以及在我目前了解的网络协议中解释了为什么网络连接需要进行三次握手。

IP、TCP、HTTP(一)
网络层级

Application Layer:  HTTP
Presentation Layer: MIME SSL TLS XDR
Session Layer:      Sockets (session establishment in TCP / RTP / PPTP)
Transport Layer:    TCP
Network Layer:      IP
Data Link Layer:    IEEE 802.2
Physical Layer :    以太网 · 调制解调器 · 电力线通信(PLC) · SONET/SDH · G.709 · 光导纤维 · 同轴电缆 · 双绞线等
 

本文主要针对:IP、TCP、HTTP三个协议,由上面的网络层级栈可以看出:

IP协议在层级中属于Network Layer

TCP协议在层级中属于Transport Layer

HTTP协议在层级中则属于Application Layer

IP(IP-Internet Protocol)网络协议
TCP三次握手

过程:

  1. 客户端首先向服务端发送一个 SYN 包和一个随机序列号 A
  2. 服务端收到后会回复客户端一个 SYN-ACK 包以及一个确认号(用于确认收到 SYN)A+1,同时再发送一个随机序列号 B
  3. 客户端收到后会发送一个 ACK 包以及确认号(用于确认收到 SYN-ACK)B+1 和序列号 A+1 给服务端

SYN 是 synchronize sequence numbers (同步序列号) 的缩写。两端在传递数据时,所传递的每个 TCP 报文段都有一个序列号。就是利用这种机制,TCP 可以确保分块传输的数据包最终都以正确的个数和顺序抵达目标端。在正式传输开始之前,源和目标端需要同步确认第一个报文的序列号。

ACK 是 acknowledgment (确认)的缩写。当某一端接到了报文包后,通过回传已报文序列号来确认接收到报文这件事。

为什么tcp建立链接需要三次握手?

理由比较简单,这个过程好像就两个接头的人之间的对话,A和B:

  1. A喊了B一句:“是B吗?”
  2. B听到了,回了一句:“我是,你是A吗?”
  3. 然后A听到B的回话,确认了对方是B,回答:“是的,我是A”

至此,双方确认彼此身份,就可以进行接下来的正式谈话了。

使用tcpdump捕捉三次握手过程

在终端上执行,先查看本地可捕捉的网络列表

$ tcpdump -D 

终端打印

1.en0 [Up, Running]
2.bridge0 [Up, Running]
3.p2p0 [Up, Running]
4.awdl0 [Up, Running]
5.utun0 [Up, Running]
6.en1 [Up, Running]
7.utun1 [Up, Running]
8.en2 [Up, Running]
9.en5 [Up, Running]
10.lo0 [Up, Running, Loopback]
11.gif0
12.stf0

选择en0进行捕捉

sudo tcpdump -c 3 -i en0 -nS host 115.29.110.64

终端打印,这个时候正在监听网络,等待访问目标地址

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes

再从一个新的终端窗口进行访问该目标地址

curl -4 http://blog.methodname.com

这个时候,之前监听的终端窗口打印

11:22:41.776205 IP 192.168.2.123.51239 > 115.29.110.64.80: Flags [SEW], seq 151278844, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1031392709 ecr 0,sackOK,eol], length 0
11:22:41.803372 IP 115.29.110.64.80 > 192.168.2.123.51239: Flags [S.E], seq 3411638797, ack 151278845, win 14480, options [mss 1452,sackOK,TS val 248265052 ecr 1031392709,nop,wscale 6], length 0
11:22:41.803472 IP 192.168.2.123.51239 > 115.29.110.64.80: Flags [.], ack 3411638798, win 4140, options [nop,nop,TS val 1031392736 ecr 248265052], length 0

打印的结果即三次握手的过程。

第一段内容:

//从客户端到服务器
IP 192.168.2.123.51239 > 115.29.110.64.80
  • 11:22:41.776205 是当前本机的时间
  • 192.168.2.123.51239是我本地的IP和端口
  • 115.29.110.64.80是访问目标的IP和端口
  • Flags 表示 TCP 报文段 header 信息中的一些缩写标识:S 代表 SYN,. 代表ACK,P 代表PUSH,F 是 FIN
  • seq是发送的随机数标识
  • win代表接收窗口大小
  • length数据长度(字节),三次握手期间均没有发送数据,所有length为0
  • options配置其它信息
[mss 1460,nop,wscale 5,nop,nop,TS val 1031392709 ecr 0,sackOK,eol]
  1. mss选项声明了最大报文长度 (Maximum Segment Size),表示接收端希望接收的单个报文的最大长度(以字节为单位)
  2. nop(no operation) ,从字面意思也看出来了,这个字段实际上是没有任何意义的字段。设计该字段主要是用来提供填充垫片。TCP的头部必须是4byte的倍数,但是大多数的TCP选项不是4byte的倍数。假如出现了整个TCP选项部分不是4byte的倍数,那么就需要使用1或多个字节无意义的nop 来填充,使之符合TCP的头部构造的规定。例如,选项部分只有6byte ,2个字节的nop就会用来做垫片
  3. wscale 是 窗口放大因子 (window scale factor)
  4. TS val 是发送方的 时间戳 (time stamp)
  5. ecr 是响应应答 (echo reply) 时间戳,通常情况下就是发送方收到的最后时间戳,(第一段内容是发送请求,所以为0)
  6. sackOK会启用选择性确认 (Selective Acknowledgement) 机制,使连接双方能够确认收到的字节范围。

第二段内容:

//从服务器到客户端
IP 115.29.110.64.80 > 192.168.2.123.51239

相比第一段多出了ack确认标识,为第一段内容的seq+1

[mss 1452,sackOK,TS val 248265052 ecr 1031392709,nop,wscale 6]

并且这个时候ecr也是有值的,因为是服务器接收到了请求并做出了响应,所以会有响应的时间.

第三段内容

//再从客户端到服务器
IP 192.168.2.123.51239 > 115.29.110.64.80

当第三次握手完成之后,客户端和服务端凭借SNY(A)ACKSNY(B)SNY-ACK完成了双方身份的确认,如果模拟为人与人之间的对话,ACK的规则即为暗号,在这三次握手过程中,双方都在一步步的试探对方的身份是否正确,当经历过三次信息(暗号)交换后,最终都确认了对方的身份,建立了信任关系,细细想来,当初设计TCP协议的人,一定是对人们日常交流方式有着足够深刻的认知,才能把这些如此巧妙的融入在互联网中。

相关

ObjC 中国 - IP,TCP 和 HTTP

OSI model