抓了个包,搞懂了网络
今天用 postman 发了请求
GET http://www.flashhost.com/check
只返回了一个字符串
success
整个过程的网络包,用 wireshark 全都抓下来了
三次握手
A->B TCP [SYN]
A<-B TCP [SYN,ACK]
A->B TCP [ACK]
HTTP 请求
A->B HTTP GET / HTTP/1.1
A<-B TCP [ACK]
A<-B HTTP 200(text/plain)
A->B TCP [ACK]
Keep-Alive
A->B TCP [TCP Keep-Alive]
A<-B TCP [TCP Keep-Alive ACK]
A->B TCP [TCP Keep-Alive]
A<-B TCP [TCP Keep-Alive ACK]
...(几分钟后)
A->B TCP [TCP Keep-Alive]
A<-B TCP [TCP Keep-Alive ACK]
四次挥手
A<-B TCP [FIN,ACK]
A->B TCP [ACK]
A->B TCP [FIN,ACK]
A<-B TCP [ACK]
这么多包,我看心情点开了 A->B 发送的第一个 HTTP 协议的包
A->B HTTP GET / HTTP/1.1
在 wireshark 里查看它的详情
aa aa aa aa aa aa bb bb bb bb bb bb 08 00 45 00 01 1d 6d 7e 40 00 80 06 00 00 c0 a8 1f a4 6e f2 44 04 db 08 00 50 2c 85 bd c9 05 ae c5 63 50 18 02 02 94 52 00 00 47 45 54 20 63 68 65 63 6b 20 48 54 54 50 2f 31 2e 31 0d 0a 0d 0a
没错,这一长串用 16 进制表示的数据,就是从网卡直接发出去的数据,一个字节都没有省略
来,给你一分钟时间肉眼拆一下包
一
分
钟
思
考
时
间
哈哈,还是我来吧
数据链路层
aa aa aa aa aa aa bb bb bb bb bb bb 08 00 45 00 01 1d 6d 7e 40 00 80 06 00 00 c0 a8 1f a4 6e f2 44 04 db 08 00 50 2c 85 bd c9 05 ae c5 63 50 18 02 02 94 52 00 00 47 45 54 20 63 68 65 63 6b 20 48 54 54 50 2f 31 2e 31 0d 0a 0d 0a
最开头是数据链路层,使用的协议是 Ethernet 以太网协议,协议格式如下:
原地址(6字节):aa aa aa aa aa aa(mac地址)
目标地址(6字节):bb bb bb bb bb bb(mac地址)
类型(2字节):08 00(ipv4)
数据:45 00 01 ... ... ...
网络层
信息太多,只提取几个关键的信息
协议:06(TCP)
源地址:c0 a8 1f a4(IP地址:192.168.31.164)
目的地址:6e f2 44 04(IP地址:110.242.68.4)
数据:db 08 00 50 ... ... ...
传输层
再次去掉网络层的 IP 协议的首部
TCP 协议大家都知道,超级多的细节,这里不展开,仍然提取关键信息,走主流程
源端口:db 08(端口号:56072)
目的端口:00 50(端口号:80)
数据:47 45 54 20 ... ..
这里的 源 和 目的 不再是 mac 地址,也不再是 IP 地址了,因为此时包已经到达了目标机器,需要找具体对应的进程,所以这里是端口号。
同样由于进程自己知道将以什么样的协议,来解读数据部分,所以这里也没有上层协议的指定,因为这已经是应用程序的事了。
我们接着拆...
应用层
再次去掉传输层的 TCP 协议的首部
就来到了我们最熟悉的应用层,使用的协议是什么呢?因为我知道我请求的服务是提供 HTTP 协议的 web 服务,同时我发送的也是 HTTP 协议的数据,所以使用的协议当然就是 HTTP 协议啦~
请求行:47 ... 0a(GET /check HTTP/1.0 \r\n)
请求头:无
请求体:无
最后:0d 0a(\r\n)