百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

14张图,让你秒懂数据在网络中到底是如何传输的

bigegpt 2024-09-03 11:03 3 浏览

之前写了不少技术科普文,不知道你看过多少?

今天老杨想提问一下:

你有想过吗,在计算机网络当中,数据是怎么样保证准确的从客户端发送到服务器端的?中间涉及到了哪些理论?

这篇文章分享的14张图,希望能助你理清数据传输的全过程。



01 客户端各层对数据的封装


java实现客户端的代码如下:


Socket socket = new Socket("192.168.3.6", 8899);


try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
     PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
) {
    printWriter.println("hello"); // 发送数据
    String line; // 读取数据
    while (null != (line = bufferedReader.readLine())) {
        System.out.println("receive message from server: " + line);
    }
}


应用层会指定发送的服务器的域名(或者IP)和端口号、以及要发送数据的内容,传递给下一层传输层。

传输层会在把应用层的报文当成自己的数据,然后在前面拼接源端口号,和目标端口号。

其中源端口号就是客户端进程监听的端口号,这个端口号一般不是固定的,由操作系统在49152~65535范围内动态分配,而目标端口号就是服务器接收数据的端口号,一般是固定的,在java代码中会指明。

网络层会在传输层报文的基础上增加源IP和目标IP,其中源IP就是本地网卡的IP地址,目标IP是服务器的IP,如果java代码中指定的是服务器的域名。

那么,首先需要通过DNS服务器将域名解析为IP,域名解析的流程:

先查浏览器缓存->操作系统缓存->hosts文件->DNS服务器。

数据链路层会在网络层的基础上增加源MAC地址和目标MAC地址,其中源MAC地址就是本机网卡的MAC地址,目标MAC地址是下一跳网络设备(一般是交换机或路由器)的MAC地址。

注意,目标MAC地址一般不是服务器的MAC地址(如果客户端和服务器端在同一个网段,那么目标MAC地址就是服务器的MAC地址),因为客户端根本就无法得知服务器的MAC地址,所以数据链路层采用下一跳的机制转递数据。

那么怎么知道我的下一跳是谁呢?

下面就要请出ARP协议了,ARP会发出一个广播,告诉全世界:“大家好,我的IP地址是192.168.1.6,我的MAC地址是00-50-56-C0-88-01

当同一个网段上的主机接收到ARP报文时,会将这些信息添加自己的ARP缓冲区中的ARP列表,同时将自己的IP地址和MAC地址回应给发送者,这样每个位于同一个网段的主机都有整个网段内各个主机的IP与MAC地址的对应关系了。

ARP列表的具体内容如下:


# arp -a
? (192.168.1.1) at 00-60-47-D4-41-A9 [ether] on eth0
? (192.168.1.7) at F8-30-F9-C1-7E-09 [ether] on eth0
? (192.168.1.100) at 00-30-F2-C1-2E-89 [ether] on eth0
... ...


现在我的目标IP是192.168.3.6,又不在这个ARP列表中,那我怎么知道目标MAC地址要填啥呢?填下一跳的MAC地址,那么下一跳是又是谁呢?这里就要请出路由表了。



# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
0.0.0.0         192.168.1.100   0.0.0.0         UG    1024   0        0 eth0


这个路由表是计算机的路由表,而不是路由器的路由表,这个路由表怎么来的呢?根据/etc/sysconfig/network-scripts/ifcfg-eth0这个文件生成的。



# cat /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
NAME=eth0
UUID=ff200252-6eac-448d-b904-a6d1a1a7da3c
ONBOOT=yes
IPADDR=192.168.1.0
NETMASK=255.255.255.0
GATEWAY=192.168.1.100
DNS1=8.8.8.8
HWADDR=00-50-56-C0-88-01


那么这个路由表怎么使用呢?将目标IP与每一条记录的子网掩码(Genmask)一一按位与运算,匹配度最高的Destination字段的IP就是下一跳的IP192.168.1.100,也就是网关地址GATEWAY,然后根据下一跳的IP去查ARP列表获得MAC地址00-30-F2-C1-2E-89

就这样客户端完成了对报文的组装,交给物理层把数据从网卡发送出去,发送到交换机A。

02交换机的交换

交换机收到客户端的报文后,会进行解析,只解析到数据链路层,从中获得目标MAC地址,然后查找ARP列表,将报文转发给对应的网卡端口。

交换机中的ARP列表:


Switch#show ip arp
Protocol  Address          Age (min)  Hardware Addr   Type   Interface
Internet  192.168.1.1             -   0060.47D4.41A9  ARPA   Vlan1
Internet  192.168.1.6             0   0050.56C0.8801  ARPA   Vlan1
Internet  192.168.1.7             0   F830.F9C1.7E09  ARPA   Vlan1
Internet  192.168.1.100           0   0030.F2C1.2E89  ARPA   Vlan1


Switch#show mac-address-table
          Mac Address Table
-------------------------------------------


Vlan    Mac Address       Type        Ports
----    -----------       --------    -----


   1    0030.f2c1.2e89    DYNAMIC     Fa2/1
   1    0050.56c0.8801    DYNAMIC     Fa0/1
   1    f830.f9c1.7e09    DYNAMIC     Fa1/1


根据目标MAC地址00-30-F2-C1-2E-89找到交换机的端口为Fa2/1,这样交换机就会把报文从这个端口发送出去,发送到路由器,这里的端口是交换机的物理端口,也就是插入网线的插口。


03 路由器的路由

路由器可以连接两个不同的网络。

路由器有一张路由表,路由表可以通过网络工程师配置或者从其他路由器学习得到。


Router(config)#do show ip route
Codes: C - connected, S - static, I - IGRP, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2, E - EGP
       i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
       * - candidate default, U - per-user static route, o - ODR
       P - periodic downloaded static route


Gateway of last resort is not set


C    192.168.1.0/24 is directly connected, FastEthernet0/0
C    192.168.3.0/24 is directly connected, FastEthernet0/1


路由器会解析报文到网络层,然后发现目的IP是192.168.3.6,从上面的路由表可以可以发现,想要去192.168.3.0网段,只需要将数据从FastEthernet0/1端口发送出去即可。

另外路由器会将目标MAC地址替换成下一跳的MAC地址(在这里是服务器的MAC地址,如果中间还有其他路由器,那么就是下一个路由器的MAC地址),怎么替换呢?还是查ARP表:


Router#show ip arp
Protocol  Address          Age (min)  Hardware Addr   Type   Interface
Internet  192.168.1.1             9   0060.47D4.41A9  ARPA   FastEthernet0/0
Internet  192.168.1.6             11  0050.56C0.8801  ARPA   FastEthernet0/0
Internet  192.168.1.7             0   F830.F9C1.7E09  ARPA   FastEthernet0/0
Internet  192.168.1.100           -   0030.F2C1.2E89  ARPA   FastEthernet0/0
Internet  192.168.3.1             11  000D.BD42.926B  ARPA   FastEthernet0/1
Internet  192.168.3.6             11  0030.A396.5DE7  ARPA   FastEthernet0/1
Internet  192.168.3.7             6   00D0.974C.0741  ARPA   FastEthernet0/1
Internet  192.168.3.100           -   00E0.B043.9302  ARPA   FastEthernet0/1


查询IP192.168.3.6的MAC地址为0030.A396.5DE7然后将目标MAC替换成这个,然后将数据从FastEthernet0/1端口发送出去,交给交换机B,交换机B再将数据转发到服务器端。


04 服务器端各层对数据的解析

服务器端收到数据后会逐层进行解析,最后将真正的数据交应用程序进行处理,至此一个数据从客户端到服务器端就完成了,服务器端会发送响应报文给客户端,大体的流程类似,但是数据不一定是原路返回的,因为中间经过的路由可能不同。

05 扩展

查看域名对应的IP:


> nslookup www.baidu.com 114.114.114.114
服务器:  public1.114dns.com
Address:  114.114.114.114


非权威应答:
名称:    www.a.shifen.com
Addresses:  183.232.231.174
          183.232.231.172
Aliases:  www.baidu.com


查看本机到服务器中间经过了多少个路由节点:


C:\>tracert 192.168.3.6


Tracing route to 192.168.3.6 over a maximum of 30 hops: 


  1   0 ms      0 ms      0 ms      192.168.1.100
  2   0 ms      0 ms      1 ms      192.168.3.6


Trace complete.


干货文章需要小友们多转发收藏,支持老杨哈。

还有什么想看的技术科普,留言告诉老杨一声,下期可能就直接更新了

相关推荐

当Frida来“敲”门(frida是什么)

0x1渗透测试瓶颈目前,碰到越来越多的大客户都会将核心资产业务集中在统一的APP上,或者对自己比较重要的APP,如自己的主业务,办公APP进行加壳,流量加密,投入了很多精力在移动端的防护上。而现在挖...

服务端性能测试实战3-性能测试脚本开发

前言在前面的两篇文章中,我们分别介绍了性能测试的理论知识以及性能测试计划制定,本篇文章将重点介绍性能测试脚本开发。脚本开发将分为两个阶段:阶段一:了解各个接口的入参、出参,使用Python代码模拟前端...

Springboot整合Apache Ftpserver拓展功能及业务讲解(三)

今日分享每天分享技术实战干货,技术在于积累和收藏,希望可以帮助到您,同时也希望获得您的支持和关注。架构开源地址:https://gitee.com/msxyspringboot整合Ftpserver参...

Linux和Windows下:Python Crypto模块安装方式区别

一、Linux环境下:fromCrypto.SignatureimportPKCS1_v1_5如果导包报错:ImportError:Nomodulenamed'Crypt...

Python 3 加密简介(python des加密解密)

Python3的标准库中是没多少用来解决加密的,不过却有用于处理哈希的库。在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto和cryptography上,我...

怎样从零开始编译一个魔兽世界开源服务端Windows

第二章:编译和安装我是艾西,上期我们讲述到编译一个魔兽世界开源服务端环境准备,那么今天跟大家聊聊怎么编译和安装我们直接进入正题(上一章没有看到的小伙伴可以点我主页查看)编译服务端:在D盘新建一个文件夹...

附1-Conda部署安装及基本使用(conda安装教程)

Windows环境安装安装介质下载下载地址:https://www.anaconda.com/products/individual安装Anaconda安装时,选择自定义安装,选择自定义安装路径:配置...

如何配置全世界最小的 MySQL 服务器

配置全世界最小的MySQL服务器——如何在一块IntelEdison为控制板上安装一个MySQL服务器。介绍在我最近的一篇博文中,物联网,消息以及MySQL,我展示了如果Partic...

如何使用Github Action来自动化编译PolarDB-PG数据库

随着PolarDB在国产数据库领域荣膺桂冠并持续获得广泛认可,越来越多的学生和技术爱好者开始关注并涉足这款由阿里巴巴集团倾力打造且性能卓越的关系型云原生数据库。有很多同学想要上手尝试,却卡在了编译数据...

面向NDK开发者的Android 7.0变更(ndk android.mk)

订阅Google官方微信公众号:谷歌开发者。与谷歌一起创造未来!受Android平台其他改进的影响,为了方便加载本机代码,AndroidM和N中的动态链接器对编写整洁且跨平台兼容的本机...

信创改造--人大金仓(Kingbase)数据库安装、备份恢复的问题纪要

问题一:在安装KingbaseES时,安装用户对于安装路径需有“读”、“写”、“执行”的权限。在Linux系统中,需要以非root用户执行安装程序,且该用户要有标准的home目录,您可...

OpenSSH 安全漏洞,修补操作一手掌握

1.漏洞概述近日,国家信息安全漏洞库(CNNVD)收到关于OpenSSH安全漏洞(CNNVD-202407-017、CVE-2024-6387)情况的报送。攻击者可以利用该漏洞在无需认证的情况下,通...

Linux:lsof命令详解(linux lsof命令详解)

介绍欢迎来到这篇博客。在这篇博客中,我们将学习Unix/Linux系统上的lsof命令行工具。命令行工具是您使用CLI(命令行界面)而不是GUI(图形用户界面)运行的程序或工具。lsoflsof代表&...

幻隐说固态第一期:固态硬盘接口类别

前排声明所有信息来源于网络收集,如有错误请评论区指出更正。废话不多说,目前固态硬盘接口按速度由慢到快分有这几类:SATA、mSATA、SATAExpress、PCI-E、m.2、u.2。下面我们来...

新品轰炸 影驰SSD多款产品登Computex

分享泡泡网SSD固态硬盘频道6月6日台北电脑展作为全球第二、亚洲最大的3C/IT产业链专业展,吸引了众多IT厂商和全球各地媒体的热烈关注,全球存储新势力—影驰,也积极参与其中,为广大玩家朋友带来了...