前言
在个人电脑上,用浏览器冲浪是再常用不过的一个操作了,但在浏览器中输入网址按下回车键背后发生的网络事件你清楚吗?
背景知识
协议栈
1、网络协议分层,其好处:
- 促进标准化工作,允许各个供应商进行开发;
- 各层间相互独立,把网络操作分成低复杂单元;
- 灵活性好,某一层变化不会影响到其它层;
- 各层间通过一个接口在相邻层上下通信。
2、PDU,即protocol data unit,每一层使用自己层的协议和别的系统的对应层相互通信,协议层的协议在对等层之间交换的信息叫协议数据单元。各层的PDU如下:
- 上层:message
- 传输层:segment
- 网络层:packet
- 数据链路层frame
- 物理层:bit
3、封装和解封装
- 封装:数据要通过网络进行传输,要从高层一层一层的向下传送,如果一个主机要传送数据到别的主机,先把数据装到一个特殊协议报头中,这个过程叫封装
封装分为:分片(和MTU、MSS有关系)和加控制头信息
- 解封装:上述的逆向过程
OSI七层 vs TCP/IP五层架构
各层地址
- 物理层:无地址,比如以太网直接是通过双绞线连接,WLAN有单独的协议保证物理层的连接;
- 链路层:MAC地址,设备出厂时会设定好,而且这个地址可以映射到网卡供应商的(OUI字段);
- 网络层:IP地址,具体分为IPv4和IPv6两种,一般有三种获取方法:静态配置、DHCP、PPPoE三种方式;
- 传输层:端口,标识某个服务(如DHCP使用UDP67和68两个端口)或程序;
- 应用层:无地址,主要依赖于网络层+传输层地址,来唯一标识一个应用,如某路由器的维护网址(http://192.168.1.1:80),实际上对应socket的原型。
涉及协议
以访问web服务器、DHCP获取PC的地址为例,其中涉及的协议有:
TCP、IP、ARP、DNS、DHCP等,具体而言:
- ARP:用于根据IP地址去查询对应主机的MAC地址;
- DHCP:用于上网主机动态获取IP地址;
- DNS:用于根据域名,解析出对应服务器的IP地址。
全过程解析
准备工作(Human)
这里以有线连接路由器LAN口为例来说明。
要上网,首先要用网线连接路由器的LAN口和PC的网口,物理层连好后,对应LAN口会发LINK UP消息给系统,进而触发下面后续操作。
这一步是人工介入的,后面多数由操作系统自动完成。
DHCP拿地址(OS)
- 链路层地址,前面提过,在网卡出厂时写死的,不需要单独的流程去获取。但PC上网需要的三层地址(IP地址),是需要额外的流程的,这里的DHCP过程就是获取IP地址用的。
- DHCP过程是操作系统自动完成的,不需要人工干预。
- DHCP这一步不再继续向下展开,实际上DHCP背后发送报文走的流程和网页数据走的TCP报文本质上是类似的。
打开网页,输入网址(www.csdn.net),按下回车(Human)
这一步是人工介入的,实际不光是打开网页,打开其他需要网络的APP,也是类似的过程。
DNS解析(Browser)
- 按下回车,此时浏览器程序会调用gethostbyname这类函数,进行dns解析。这里涉及DNS协议的实现,根据配置文件情况,可能从本地缓存查询,也可能向DNS服务器发起DNS请求(或UDP或TCP);
hptr=gethostbyname(“www.csdn.net”)
- 解析的结果是根据域名查到了服务器的IP,比如根据www.csdn.net查到了其IP地址为47.95.164.112地址,此时浏览器程序获得服务器地址。
- DNS解析这一步不再继续向下展开,实际上DNS解析中gethostbyname背后发送数据走的流程和网页数据走的TCP报文本质上是类似的。
建TCP连接(Browser)
- 浏览器根据前一步DNS解析获得的IP地址,建立TCP socket(实际中是哪种类型的socket,跟具体的业务有关,HTTP是基于TCP的),并发起GET请求(HTTP协议),获取数据。
- 获取数据之后,将其显示在页面上。
- 下面是用C实现的部分获取页面信息的伪码,实际浏览器的逻辑类似:
/*create socket*/ struct sockaddr_in si; si.sin_family = AF_INET; si.sin_port = htons(80); si.sin_addr.S_un.S_addr = inet_addr(ipstr); int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1 || sock == -2) return ; /* connect server */ connect(sock, (SOCKADDR*)&si, sizeof(si)); /*send request to http server*/ char request[1024] = "GET /?st=1 HTTP/1.1\r\nHost:"; strcat(request, host); strcat(request, "\r\nConnection:Close\r\n\r\n"); int ret = send(sock, request, strlen(request), 0); /*get web page contents*/ FILE *f = fopen("recieved.txt", "w"); int isstart = 0; while (ret > 0) { const int bufsize = 1024; char* buf = (char*)calloc(bufsize, 1); ret = recv(sock, buf, bufsize - 1, 0); fprintf(f, "%s", buf); free(buf); } fclose(f); closesocket(sock);
传输层转发(TCP/IP协议栈-TCP)
在上一步建立TCP socket等相关操作,背后是大名鼎鼎的TCP三次握手:
路由转发(TCP/IP协议栈-IP层)
- IP层收到TCP层发来的报文后,根据目的IP(本文的csdn网站对应的IP地址)去查路由表,找到对应的表项(接口、下一跳),构建IP报文并从对应接口发送出去。
- 构造IP报文的时候,会去邻居系统查找下一跳IP对应目的MAC;
- 一台windows电脑的典型IP路由表如下:
Active Routes: Network Destination Netmask Gateway Interface Metric 0.0.0.0 0.0.0.0 10.42.113.129 10.42.113.132 20 10.42.113.128 255.255.255.192 10.42.113.132 10.42.113.132 20 10.42.113.132 255.255.255.255 127.0.0.1 127.0.0.1 20 10.255.255.255 255.255.255.255 10.42.113.132 10.42.113.132 20 127.0.0.0 255.0.0.0 127.0.0.1 127.0.0.1 1 224.0.0.0 240.0.0.0 10.42.113.132 10.42.113.132 20 255.255.255.255 255.255.255.255 10.42.113.132 10.42.113.132 1 Default Gateway: 10.42.113.129
ARP解析(TCP/IP协议栈-ARP)
- ARP相关模块,也可以叫邻居子系统,主要用于维护目的IP和目的MAC的对应关系。
- 有本地有缓存,如果没有缓存则发起ARP请求去获取。
- 一个windows下的ARP表如下:
C:\Users\1024>arp -a 接口: 10.40.164.55 --- 0xb Internet 地址 物理地址 类型 10.42.164.2 74-41-14-16-ad-c0 动态 10.42.164.3 00-11-5e-00-01-01 动态
数据链路层(Windows驱动)
- 前面IP层找到对应出接口后,会调用对应接口的驱动发送函数将报文。
- 驱动发送报文的实质,就是操作PC机的网卡,将报文交给网卡发出。
物理层(网卡&网线)
- 以太网卡中数据链路层的芯片一般简称之为MAC控制器,物理层的芯片我们简称之为PHY,而许多网卡的芯片把MAC和PHY的功能做到了一颗芯片中。
- 数据从驱动下到MAC控制器,经由PHY,送到RJ45接口,之后数据就以物理信号的形式从网线传出去了。
总结
- 本文仅以有线为例来说明PC DHCP获取地址,有线上网的全过程,实际上无线上网、PPPoE方式也类似,读者可触类旁通。
- 最后盗张图整体看下浏览器上网过程中,上层应用数据的经过各的各组件以及其变化。
参考资料
- 《TCP/IP详解》
- 《网络是怎样连接的》