之前一直听别人说Wireshark这个抓包软件,Leelom也跟我提过说面试的时候会问这些东西。今天呢,参考别人的博文,结合抓包,将TCP/IP协议进行一些浅显的分析。
1. HTTP协议
在介绍TCP协议之前,首先介绍一下HTTP协议,因为http协议是基于TCP协议的。之前你做爬虫那些抓包然后 get/post 请求的时候,就是在利用http协议。
http(HyperTextTransferProtocol),是基于TCP/IP协议,可以用来传输数据、文件、图片等等,默认为80端口。他是用于从万维网服务器传输超文本到用户端的传送协议。
是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型
基本特征
-
无连接:上面说了,http协议是由请求和响应构成。无连接是说每次只处理一个请求。服务器处理完客户请求后,即断开连接。
采用无连接可以节省传输时间。
但是同时,由于传输图片的出现,每次访问建立一次TCP连接就显得很低效,所以就有了 keep-alive功能的出现,使得SerCli端保持连接。 - 媒体独立性:所谓媒体独立性就是说 http 协议是与传输内容独立的,只要SC都知道如何处理数据内容,那么任何类型的媒体数据都可以发送。
-
无状态:由于是无连接的,所以http也就是无状态的。意思就是SC二者只在连接存在的期间知道彼此,断开连接之后就不知道对方了。所以SC都不能在不同的网页的不同的请求之间保留信息。
但是有时候又需要保留信息,所以就出现了 cookie 和 session。
更加具体的说明需要重新写一篇博客来看。参考http详解
2. TCP协议
基础认知
TCP(Transmission Control Protocol,传输控制协议)是面向连接的、可靠的、基于字节流的 在 传输层 上的通信协议。这里想一下UDP,是无连接的、不可靠的(所以就像之前提到的一样,无连接的快节省时间,不用连接建立的时间)。
TCP/IP分层结构
跟OSI(Open System Interconnection)分7层不同。如上面的图中,TCP/IP 协议下分为4层:应用层、传输层、网络层、数据链路层。
- 应用层:向用户提供常用的应用程序。比如电子邮件、文件传输、远程登录等。TELNET 会话提供了基于字符的虚拟终端,FTP使用 FTP协议来提供网络内机器间的文件拷贝功能。
- 传输层: 传输层提供两台主机之间端到端的通信。所谓的TCP/UDP协议就是跑在这一层。
- 网络层:处理分组在网络中的活动。可以理解为IP路由这些。
-
链路层:链路层负责处理下层物理层的物理接口细节。主要目的有:
\ 1. 为上层IP模块接收和发送IP数据报
\ 2. 为ARP模块发送请求和完成接收
\ 3. 为RARP模块。。。。
封装
封装这个事情就好像寄快递一样。之前上计网课那个张洪涛就是这么举例子的。
注意上图中的 appl 首部是说 application 层首部的意思。
按照上图一层层封装,直到经过以太网封装之后,就要通过网线或者其他的传输介质将此封装好的报文发送到另一端去。另一端收到之后再一层层的把封装头剥离,最终拿到用户数据。这里我们要明白一点就是上层对下层不负责,下层对上层隐身。
TCP/IP
这里可以做这样的一个理解,就是TCP/IP协议是说二者协同一起工作。
其中TCP负责应用软件(浏览器)和网络软件之间的通信,IP负责计算机之间的通信(路由)。
TCP负责将数据分隔并装入IP包,并接收时组合,IP负责把包发给接受者。
TCP报文格式
Wireshark 抓包分析
首先启动wireshark,然后选择要抓取的网络端口进行抓取。选定TCP包(绿色的)。如下图
从上到下,分别对应4层:物理层、数据链路层、IP层、传输层。
A. 第一行, Frame 595 是要发送的数据块,抓到的帧的序号是 595,捕获的字节数等于传送的字节数 1486B
B. 第二行,以太网,有线局域网技术,属于数据链路层。这里可以看到源Mac地址是 00:74:9c:7d:fd:ab,目的Mac是 74:46:a0:b4:fa:c5
C. 第三行,IPV4协议,是网络层,也称为网际协议,这里可以看到源IP和目的IP
D. 第四行,TCP协议,是传输层。源端口,目的端口,序列号,ACK是TCP报包头的确认标志,这里应该是返回ack number。
下面看一下每一行内容的详细信息。
-
物理层:
Frame
protocols in frame: eth:ethertype:ip:tcp 帧内封装的协议层次结构
Coloring Rule Name: ICMP 着色标记的协议
-
数据链路层:
Ethernet
Type: IPV4(0x0800) 类型是IP数据包
-
IP层
IP - TCP 层
TCP
这里TCP通信标明的端口号就是用来通信的,是进程间通信。
A. Acknowledgement Number : 这是接收端所期望接收到的下一个顺序号(只有在ACK标志位,Flags中,是1时候才有效,代表接收确认)。所以来说 TCP 连接是需要一个全双工的通信。
到这里,总结一下。以太网头部14字节, IP报头部为20字节,TCP报头部最小是20字节/UDP头部 8字节。
3. TCP的三次握手 & 四次挥手
三次握手(2次确认)
这里首先看一下3次握手的示意图。
这里需要明白几个标志位:
- ACK(acknowledgement):确认序号有效。前面说过
- SYN(Synchromize):发起一个新链接
- FIN(Final):释放一个链接
第一次握手:
Client 将标志位的 SYN 置1,随机产生一个 Seq,将数据包发送给 Server
Client 进入SYN_SENT 状态,等待 Server 确认
第二次握手:
Server 收到SYN=1的数据包后,知道客户端请求建立一个链接,Server端将 SYN 和 ACK 都置1,随机产生一个 Seq=y,将数据包发送给 Client
Server进入 SYN_RCVD 状态。
第三次握手:
Client 收到 后若ACK为1,则将数据包 ACK=1,ack = K+1发送给 Server,此时 Server检查ACK=1则连接成功建立,二者进入 ESTABLISHED 状态完成三次握手,传输数据。
为什么不是4次或者2次
为什么不是4次
没必要。3次已经确认双方功能正常,可以进行全双工通信。
- 第一次握手:Client什么都不能确认;Server确认了对方发送正常,自己接受正常
- 第二次握手:Client确认了自己发送/接收正常,对方发送接收正常;Server确认了自己接收正常,对方发送正常。
- 第三次握手:都正常。
就是说在CS两端,都要确认双方收发正常。
为什么不是2次
有这样一种情况,由于阻塞,所以A到B的消息没有及时到达B,A以为超时,所以重新发出消息报。而这时候堵塞的到了B,B以为是新的连接请求,于是向A发出确认报文,此时如果是2次握手,那么B认为连接已经建立,于是监听A发来的报文。然而由于A没有发出建立连接请求,所以并不会理会。于是B的资源白白浪费了,这在服务器中是不允许的。
所以需要3次握手,2次确认。
主要为了防止已经失效的报文影响,使得服务端处于连接建立 established 状态。
[这里还有一个从 seq number 的角度来理解的例子],主要就是说要同时让双方发送的 seq number 都得到确认,但是两次握手只能使得发送方的 seq 得到确认。(https://blog.csdn.net/lengxiao1993/article/details/82771768)
还有一个理解的角度,可以从 全双工通信的角度来说。
四次挥手
- 第一次挥手:数据传输结束后,Client 停止发送数据,发出连接释放报文。
- 第二次挥手:Server 收到报文,发出确认报文。这时候连接处于 半关闭状态。Server 仍然可以给Client发报文,但是Client 不会再发报文。
- 第三次挥手:等到Server报文发完后,应用进程就通知 Server 释放TCP连接。此时Server发送最后一个报文: FIN=1,ACK=1,seq=w,ack=u+1
- 第四次挥手:Client收到Server的释放报文后,发出确认。之后经过 2MSL(最长报文端寿命)后,连接最终释放。
为什么比握手多一步?
因为这里涉及一个问题:握手时,Server的ACK和SYN一起发的;但是在挥手时,可能Server的报文还没有发完,所以需要分开两步,第一步发 告诉Client 你发的我收到了,之后自己报文发完,才能发 FIN报文。
主要是说有一个 半关闭状态。
为什么Client要等待
超时重传,为了避免最后一个 c-s 的包丢失,造成 s 不能关闭连接。