问:数据包怎样在链路上传播并到达目标主机?
前提:数据要想传递到目标主机,首先本机数据包需要到达网络上,经网络传输到达目标主机
数据在到达网络会经过OSI七层模型对数据进行封装,做些处理。
OSI七层参考模型
应用层
表示层
会话层 http/https协议
传输层 tcp/udp协议
网络层 ip/icmp/igmp协议
链路层 arp/rarp协议
物理层 type B/C接口
打开电脑
- 打开Google浏览器(应用层的应用app)
- 页面显示文字信息(表示层,若出现页面乱码则是表示层出现问题,改一下编码格式)
- 输入URL即是想跟目标主机建立会话,建立会话依赖于数据包到达目标主机并建立连接
输入url点击enter
- 浏览器会查找浏览器dns缓存,找到域名对应的IP地址
- 浏览器无,查找本机dns缓存(system/hosts)
- 本机无,发送udp请求本地的dns缓存服务器
- 第三步基本已经能获取到IP地址,若无,话题就比较深了,自个百度。
到此获取到目标主机的IP地址
假设url为:www.baidu.com/s?ie=UTF-8&wd=漯河
IP地址为:202.108.22.5/80
在数据传输之前,需要进行三次握手与目标主机建立socket连接,进行如下操作
根据TCP协议,会发送一个tcp报文段 (包含:本机端口和目标主机端口syn=1和随机生成的seq=110)
本机端口在0-65535之间随机生成,目标端口即是80
tcp报文段经IP协议封装成一个ip数据报 (即在报文段前加上本机ip和目标主机ip地址)
ip数据报经链路层会封装成一个数据帧 (链路上传播的叫数据帧)
数据帧即是在ip数据包前加上本机Mac地址与下一跳的Mac地址
怎样获取MAC地址?
本机会根据目标IP地址和子网掩码判断是否跟自己在同一局域网,
若在,则发起rap广播,目标主机收到回给出arp应答,arp包里装有目标MAC地址。
若不在,说明需要经过路由器、因特网,则下一跳即是(你家的路由器)连接因特网的路由器mac地址(即网关)
路由器的Mac地址是通过arp高速缓存获取
至此一个完整的数据帧封装完成
当数据帧顺着链路到达路由器,路由器发现目标Mac是自己,就会把以太网帧打开,拿到目标主机的IP地址根据路由表选择下一跳的ip地址,再根据arp缓存获取MAC地址,再封装成以太网帧,再传输到下一个路由器,再拆开以太网帧,比较目标IP地址是否是自己。
若不是,接着下一跳,直到这个以太网帧顺着链路到达目标主机所在局域网的路由器,路由器拆开以太网帧拿到目标主机的IP地址,与路由器所在的局域网的子网掩码与操作,发现这个IP地址属于这个局域网,就会发起一个arp请求在局域网里广播,不是目标主机收到这个请求就会丢掉,是目标IP主机就会响应,返回自身的MAC地址给路由器,路由器就会再次封装成帧,下一跳的地址就是目标主机。
至此第一次握手的数据包到达目标主机
目标主机依次拆开以太网帧,显现出ip数据包,再拆开ip数据报,获取到tcp报文段,显现出=> syn=1 (请求连接), seq=110(序列号)
于是根据TCP协议就会生成一个syn=1, ack=111,seq=333(随机数)的一个tcp报文段,
经过IP层加上本机ip和目标ip(客户端主机),变成IP数据报,经过链路层再加上本机Mac地址和网关Mac地址,封装成以太网帧,并根据路由在网络中进行传输,到达客户端主机。
至此第二次握手的数据包到达客户端主机
客户端主机经层层剥开加的IP头、Mac头,获取到tcp报文段,显现出=>syn=1, ack=111 ,seq=333
syn表示目标主机想要和客户端主机建立连接
ack=111=110+1 说明是目标主机的响应
于是根据TCP协议就会生成一个ack=334的一个tcp报文段,
经过IP层加上本机ip和目标ip,变成IP数据报,经过链路层再加上本机Mac地址和网关Mac地址,封装成以太网帧,并根据路由在网络中进行传输,到达目标主机。
至此三次握手完毕,封装发送的数据
根据www.baidu.com/s?ie=UTF-8&wd=漯河 生成get请求http报文
请求行:
GET s?ie=UTF-8&wd=漯河 HTTP/1.1
请求方式 资源路径?查询字符串 协议名/版本
请求头:
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive
请求空行