当前位置 博文首页 > 码农之家:【TCP/IP】从在浏览器中输入网址按回车键说起

    码农之家:【TCP/IP】从在浏览器中输入网址按回车键说起

    作者:[db:作者] 时间:2021-07-30 20:54

    前言

    在个人电脑上,用浏览器冲浪是再常用不过的一个操作了,但在浏览器中输入网址按下回车键背后发生的网络事件你清楚吗?

    背景知识

    协议栈

    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详解》
    • 《网络是怎样连接的》
    cs