网络层级

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