文章目录

  • 开篇问题
  • 网络为什么要分层?
    • 程序是如何工作的?
    • 层与层之间的关系
  • 小结

开篇问题

TCP 在进行三次握手的时候,IP层和 Mac 层对应有什么操作呢?

从原始地址 A 到目标地址 D,中间经过两个中转站 A->B->C->D,是通过路由转发的。
那 A 知道自己的下一个中转站是 B,那从 A 发出来的包,应该把 B 的 IP 地址放在哪里呢?B 知道自己的下一个中转站是 C,从 B 发出来的包,应该把 C 的 IP 地址放在哪里呢?如果放在 IP 协议中的目标地址,那包到了中转站,怎么知道最终的目的地址是 D 呢?

我们常听说二层设备、三层设备。二层设备处理的通常是 MAC 层的东西。那我发送一个 HTTP 的包,是在第七层工作的,那是不是不需要经过二层设备?或者即便经过了,二层设备也不处理呢?或者换一种问法,二层设备处理的包里,有没有 HTTP 层的内容呢?

最终,可以结合为一个综合的问题。从你的电脑,通过 SSH 登录到公有云主机里面,都需要经历哪些过程?或者说你打开一个电商网站,都需要经历哪些过程?说得越详细越好。

网络为什么要分层?

这个问题,可以给自己建立一个认知:复杂的问题和程序常常都要分层解决。

想象网络包就是一段 Buffer,或者一块内存,是有格式的。同时,想象自己是一个处理网络包的程序,而且这个程序可以跑在电脑上,可以跑在服务器上,可以跑在交换机上,也可以跑在路由器上。你想象自己有很多的网口,从某个口拿进一个网络包来,用自己的程序处理一下,再从另一个网口发送出去。

当然网络包的格式很复杂,这个程序也很复杂。复杂的程序都要分层,这是程序设计的要求。比如,复杂的电商还会分数据库层、缓存层、Compose 层、Controller 层和接入层,每一层专注做本层的事情。

程序是如何工作的?

我们可以简单地想象“你”这个程序的工作过程。

当一个网络包从一个网口经过的时候,你看到了,首先先看看要不要请进来,处理一把。有的网口配置了混杂模式,凡是经过的,全部拿进来。

接收解析

拿进来以后,就要交给一段程序来处理。假设是process_layer2(buffer)。程序明白其中的意思,从 Buffer 中,摘掉二层的头,看一看,应该根据头里面的内容做什么操作。

假设你发现这个包的 MAC 地址和你的相符,那说明就是发给你的,于是需要调用
process_layer3(buffer)。这个时候,Buffer 里面往往就没有二层的头了,因为已经在上一个函数的处理过程中拿掉了,或者将开始的偏移量移动了一下。在这个函数里面,摘掉三层的头,看看到底是发送给自己的,还是希望自己转发出去的。

如何判断呢?如果 IP 地址不是自己的,那就应该转发出去;如果 IP 地址是自己的,那就是发给自己的。根据 IP 头里面的标示,拿掉三层的头,进行下一层的处理,到底是调用
process_tcp(buffer) 呢,还是调用 process_udp(buffer) 呢?

假设这个地址是 TCP 的,则会调用process_tcp(buffer)。这时候,Buffer 里面没有三层的头,就需要查看四层的头,看这是一个发起,还是一个应答,又或者是一个正常的数据包,然后分别由不同的逻辑进行处理。如果是发起或者应答,接下来可能要发送一个回复包;如果是一个正常的数据包,就需要交给上层了。交给谁呢?是不是有 process_http(buffer) 函数呢?

没有的,如果你是一个网络包处理程序,你不需要有 process_http(buffer),而是应该交给应用去处理。交给哪个应用呢?在四层的头里面有端口号,不同的应用监听不同的端口号。如果发现浏览器应用在监听这个端口,那你发给浏览器就行了。至于浏览器怎么处理,和你没有关系。

封装发送请求

而浏览器自然是解析 HTML,显示出页面来。电脑的主人看到页面很开心,就点了鼠标。点击鼠标的动作被浏览器捕获。浏览器知道,又要发起另一个 HTTP 请求了,于是使用端口号,将请求发给了你。

你应该调用send_tcp(buffer)。不用说,Buffer 里面就是 HTTP 请求的内容。这个函数里面加一个 TCP 的头,记录下源端口号。浏览器会给你目的端口号,一般为 80 端口。然后调用send_layer3(buffer)。Buffer 里面已经有了 HTTP 的头和内容,以及 TCP 的头。在这个函数里面加一个 IP 的头,记录下源 IP 的地址和目标 IP 的地址。

然后调用send_layer2(buffer)。Buffer 里面已经有了 HTTP 的头和内容、TCP 的头,以及 IP的头。这个函数里面要加一下 MAC 的头,记录下源 MAC 地址,得到的就是本机器的 MAC 地址和目标的 MAC 地址。不过,这个还要看当前知道不知道,知道就直接加上;不知道的话,就要通过一定的协议处理过程,找到 MAC 地址。反正要填一个,不能空着。

万事俱备,只要 Buffer 里面的内容完整,就可以从网口发出去了,你作为一个程序的任务就算告一段落了。

层与层之间的关系

知道了上面的过程后,其实分层最重要的是要体现处层层封装的过程。
另外对于开篇的问题:

  1. 在 TCP 三次握手的时候,IP 层和 Mac 层在做什么,当然是 TCP 每发送一个消息,都会带着 IP 层和 MAC 层。 TCP 每发送一个消息,IP 层和 MAC 层的所有机制都要运行一遍。对 TCP 协议来说,三次握手也好,重试也好,只要想发出去包,就要有 IP 层和 MAC
    层,不然是发不出去的。所以如果一个 HTTP 协议的包跑在网络上,它一定是完整的。无论这个包经过哪些设备,它都是完整的。
    只要是在网络上跑的包,都是完整的,可以有下层没上层,绝对不可能有上层没下层
  2. 所谓的二层设备、三层设备,都是这些设备上跑的程序不同而已。一个 HTTP 协议的包经过一个二层设备,二层设备收进去的是整个网络包。这里面 HTTP、TCP、 IP、 MAC 都有。什么叫二层设备呀,就是只把 MAC 头摘下来,看看到底是丢弃、转发,还是自己留着。那什么叫三层设备呢?就是把 MAC 头摘下来之后,再把 IP 头摘下来,看看到底是丢弃、转发,还是自己留着。

小结

理解网络协议的工作模式,有两个小窍门:

  • 始终想象自己是一个处理网络包的程序:如何拿到网络包,如何根据规则进行处理,如何发
    出去;
  • 始终牢记一个原则:只要是在网络上跑的包,都是完整的。可以有下层没上层,绝对不可能
    有上层没下层。

网络为什么要分层—程序如何工作相关推荐

  1. 计算机网络协议的缺点,对网络协议的分层处理的优缺点

    网络协议通常分不同层次进行开发,每一层分别负责不同的通信功能.一个协议族,比如TCP/IP,是一组不同层次上的多个协议的组合.TCP/IP通常被认为是一个四层协议系统,对网络协议的分层处理的优缺点是什 ...

  2. OpenFlow网络中处理正常流量的工作流程

    OpenFlow网络中处理正常流量的工作流程 在OpenFlow网络中,控制平面中的控制器通过两种方式在数据平面上安装流规则来控制整个网络的行为:主动流安装和反应流安装. 在主动方法中,控制平面在数据 ...

  3. 写一个java的网络数据包分析程序(一)

    需要写一个工具监控我所负责项目中的服务器与客户端的交易事件,而我又不方便修改系统代码(因为此工具只是我自己为了工作方便而作),因此需要通过监听并分析网络数据包来获取信息. 原本打算将tcpdump的C ...

  4. C++-网络库:Poco概述【开源的C++类库的集合】【提供简单的、快速的网络和可移植应用程序的C++开发】【和C++标准库可以很好的集成并填补C++标准库的功能空缺】【适合嵌入式开发】

    学习一个框架前,要先明白它的是什么,为什么,怎么用.下面这些文字,是从中文poco官网上转过来的,正如poco c++库的特点,非常清晰,代码风格更是一目了然: poco开发库的特点,非常适合写后台处 ...

  5. 网络木马丛生安全软件如何工作

    网络木马丛生安全软件如何工作 "红灯停.绿灯行"这是一个交通规则,但这绝不仅仅是针对司机的,我们每个人都应该了解与遵守. 因为,虽然我们不开车,但却存在被车撞的危险. 所以,本文虽 ...

  6. 音乐雷达 shazam算法_shazam等音乐搜索应用程序的工作背后,创建您自己的音乐搜索应用程序...

    音乐雷达 shazam算法 Ever wondered how your favorite music searching app works?. Well, this is the correct ...

  7. 程序猿工作效率的影响因素和管理者怎样推断

    看了一篇博客<为什么程序猿的工作效率跟工资不成比例!>有感而发. 影响工作效率的因素主要有三:能力,经验,责任心.这三者相辅相成缺一不可. 没有能力,遇到没有遇到过的问题,就非常难解决.而 ...

  8. 一位程序员工作10年总结的13个忠告

    一位程序员工作10年总结的13个忠告 展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告. 走过的路,回忆起来是那么曲折,把自己的一些心得体会分享给程序员兄弟姐妹们,虽然时代 ...

  9. QT5获取运行程序的工作目录与程序所在的目录

    在qt-creator中debug的时候,发现程序不能读写所在目录的配置文件,资源文件. Google了一下,原来 运行程序的 工作目录 与 程序所在的目录是不同的概念. 跑跑这段代码就知道了: #i ...

最新文章

  1. Windows XP下vs2010中配置OpenCV2.4.3
  2. android adb端口被占用问题解决办法
  3. linux应用程序调试方法,Linux应用程序使用写文件调试程序的方法
  4. 玩转oracle 11g(2):创建数据库
  5. python nlp data_Python nlpaug包_程序模块 - PyPI - Python中文网
  6. Linux下SVN创建新的项目
  7. 升级到新SQL Server版本
  8. middleware什么意思_middleware
  9. 锐捷交换机常用命令速查
  10. linux 不小心删除ls,浅谈Linux系统误删除文件恢复方法
  11. 4TB的移动硬盘,显示只有1.63TB
  12. 2022-2028全球与中国应急服务5G技术市场现状及未来发展趋势
  13. 在 PostgreSQL 中简单实现 Insert ignore 操作
  14. 洗车行业可以使用会员管理系统吗?
  15. jquery.form.js的ajaxSubmit和ajaxForm使用(用于多文件上传以及其他参数的混合提交)
  16. 跨境电商淘系、阿里巴巴海外站、外贸站搭建,代购系统源码PHP前端源码展示
  17. NOI模拟(5.23) TJOID2T3 教科书般的亵渎 (bzoj5339)
  18. Java基础打印日历——知道1901.1.1是星期二
  19. 鸿蒙系统依靠高通芯片,鸿蒙系统+高通芯片合体!iPhone再见了
  20. 可以在网上接单以及把自己作品上传到一些设计平台

热门文章

  1. continue和break的区别,以及如何跳出多重循环(或者判断)语句
  2. 大林算法,比较基础的,无振铃的改了对象需要手动改一下
  3. ECC加密;easy_ECC
  4. Google Instant Apps
  5. Java--配置环境变量
  6. React的Context
  7. 卷积神经网络中卷积的作用与原理
  8. RESTFul与RESTFul案例
  9. Linux FUSE开发
  10. 华夏芯闪耀登场第四届“芯动北京“论坛