欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > Linux网络编程之——网络初认识

Linux网络编程之——网络初认识

2025/3/12 22:54:16 来源:https://blog.csdn.net/newbie5277/article/details/145863629  浏览:    关键词:Linux网络编程之——网络初认识

目录

Linux网络

独立模式

网络模式

局域网LAN和广域网WAN

协议

协议的分层

网络协议栈

OSI七层模型

TCP/IP 五层(四层)模型

TCP/IP网络协议栈和操作系统的关系

再次理解网络协议栈

局域网内计算机通信原理 

不同局域网间计算机的通信原理

 数据包的封装


在前面的文章中,我们已经学习完了Linux系统编程方面的知识,接下来我们就要开始进入Linux网络编程部分了。

在正式认识Linux网络编程前,我们先对网络做一个了解。

Linux网络

我们知道网络的出现主要解决了多设备之间的数据传输问题,即使相隔很远,我们也可以通过网络发送和接受消息实现即时通讯。那么我们思考一下,在网络出现之前是如何实现数据的传输和通信的呢?这就要讲一下网络的发展过程了。

独立模式

在网络出现之前,计算机之间都是处于一种各自独立的状态,多个计算机之间是无法直接传输数据的。如果需要多个计算机之间协同处理一个业务,则需要一个可以存储数据的中间介质,如硬盘。在第一个计算机上处理完后将处理完的数据通过硬盘传输到后面的计算机中,最终得到最后的业务处理结果。

网络模式

网络的出现极大地提高了多个计算机之间协作的效率。要想先理解网络,我们先需要再回忆一下计算机的结构,我们知道目前大多数的计算机结构都是按照 冯诺依曼体系 设计的。也就是说计算机的框架是由输入设备、输出设备、存储器、中央处理器(CPU)组成的。

 而且计算机内部的各种硬件也都是需要数据交互的,它们之间的交互实际上就是通过主板中的链接着各硬件的线路来交互的。一台计算机内部存在着许多的设备和连接线路,并且设备之间可以通过这些线路来进行数据交互。


基于上面呢启发,在多台计算机中,我们是否能也可以像一个计算机的内部那样通过线路将这些计算机连接起来从而实现多台计算机之间的数据交互呢?

我们首先考虑在两台计算机之间的可能性。计算机中存在一个称为 网卡 的输入输出设备,通过“一根线”将两台计算机的网卡连接起来,这样就实现了两台计算机的数据交互。这根线就可以看作“网线”,这两台通过该网线连接起来的计算机就可以看作一个只有两台计算机的 “网络”。同样,多台计算机之间也可以通过此方法连接。

既然两台计算机通过线路链接起来,进而可以传输数据,可以看作“网络”。那么上面说到一个计算机的内部设备其实都是通过不同的线路连接起来的,并且也可以相互传输数据,那么我们也可以将计算机内部的结构看作一个小型的网络结构。

那么我们再理解一下多台计算机之间的连接,其实就是将他们的网卡设备通过线路连接起来了。只不过相比于计算机内部的线路,该线长多了。但是无论是线长还是线短,都存在着各自的缺点,计算机内部线短且密,这些线路之间的数据传输容易造成数据干扰。同时线长所面临的问题如下:

  • 可靠性:线长的话在数据传输的过程中容易产生数据丢失和损坏的问题。
  • 效率:线越长数据传输所需要的时间越长,传输效率越低。
  • 如何定位接收方:在这么长的传输线下,如何找到传输数据的目的地呢。

现代的网络基本都是围绕着线太长所导致的上述问题展开的。

局域网LAN和广域网WAN

当我们需要连接的计算机越来越多时,整个网络越来越大时,为了方便网络连接,保持稳定,此时就诞生出了一些设备:交换机、路由器等。

  • 交换机:通常用于在同一个计算机网络中连接多个设备,并通过网络协议来实现数据的传输和交换。因为计算机太多连接会产生一些诸如安全性和传输效率的问题,所以引入交换机。
  • 路由器:当不通过的计算机网络之间也需要交换数据时,就要使用路由器将不同的计算机网络连接起来。交换机会根据 不同网络的网络协议来实现数据包的转发,以此来实现网络之间的通信。

所以当网络之间通过交换机、路由器连接起来形成更大的网络时,局域网就诞生了。

但是局域网一般不会太大,上面的几个计算机直接连接在一起的例子就可以称为一个局域网,更大的网络就是“广域网WAN”等。

协议

协议,从字面意思来讲就是双方共同商量的一种约定,在网络中,即为数据发送方和数据接收方共同的一个约定。双方在发送数据和接收数据时必须按照协议中的规则执行。

计算机内部传输数据的时候都是以二进制形式传输的,如果各设备之间不对二进制数据约定好读取、发送的协议,就没办法正常的发送和获取数据。

在网络中同样如此,在网络中各计算机之间传输数据也是通过二进制的方式传输的。但是二进制的方式可能不同,有些可能会用频率的强弱来表示1和0,有些可能使用信号的波峰波谷来表示。即不同的主机之间虽然都是二进制的形式传输信息,但是由于表示的形式不同,这些二进制数就不一定会被正确的、正常的读取到。所以,在传输数据时,就需要提前约定好传输的数据格式。

但是只约定好数据格式是不能做好不同主机之间的通信的,还需要遵守制定好的标准。这是什么原因呢?

  • 计算机的生产厂家有很多,每个厂家计算机内部实现通信的方式就会有不同。
  • 计算机的操作系统也有很多,不同的操作系统内部数据的表现形式也会有不同。
  • 计算机网络硬件设备同样很多,不同的设备之间也会存在大大小小的差异。

为了将这些差异化统一起来,就必须制定一个让所有厂商、操作系统、网络硬件共同约定的一个标准。这个标准就可以被称为 网络协议网络协议一般包括了数据传输的格式、传输速率、错误检测与纠正等方面的规定,以方便数据的传输、主机之间的通信

协议的分层

学到这里,我们其实已经对 “分层”这个词有了一定的了解,之前在介绍Linux的程序地址空间的时候,这其实就是一种软件分层。系统是一层,中间是一层,还有上层的软件或底层的硬件又是一层。

那么为什么要费劲地进行分层呢?

  1. 对软件进行分层的同时,实际上对软件的问题也进行了分类。即不同层之间的关系就是调用与被调用之间的关系,当我们发现某个问题后,我们直接可以通过定位层级来定位具体的问题。
  2. 软件分层本质上实际就是软件上的解耦。
  3. 软件分层同样利于我们对代码进行分析。

同样,网络协议也是可以进行分层的。

为了方便理解,我们举一个现实中的例子来说明网络协议的分层:生活中的打电话

       在生活中,我们在打电话的时候,一般情况下一定是使用相同的语言来进行交流的,并且在我们打电话时,我们所认为的是自己是与对方直接进行通话的。
       但是,事实上,双方并不是直接通信。我们可以将在打电话时所使用的语言看作 在人的层面使用的一种语言协议。且我们在电话通讯时,先是将我们的说话声音传输到通讯设备中,此时是一种模拟信号,接着将模拟信号转成数字信号再进行传输。所以说,我们就可以将打电话的过程看作最简单的两个层级:

  • 人,即用户层级,人与人之间通过一定的语言(协议)进行通信。
  • 设备层级,设备之间通过一定的协议 传输数字信号

      那么为什么再打电话的时候我们会认为是自己与对面的人直接通信呢?这是因为我们再打电话的时候不会去关心中间的数据是以怎么样的形式存在的或者是以怎么样的形式传输的。同理,设备之间传输也不会在意打电话的人说的是什么语言,说的语速有多快等。

    所以打电话也可以被看作是人与人通信,同样,也可以看作是设备与设备之间的通信。

        所以我们可以进一步看作:同层协议设备之间直接通信,可以忽略底层的网络。也就是说,网络协议是分层的,不同层就必须有自己的协议以便同层之间的交流。

       所以在分层之后,不同层级之间进行数据传输只需要 调用不同层级提供的接口就可以了 ,并不需要关注底层是如何实现的

网络协议栈

上面说到网络协议是分层的,接下来就具体看看分多少层,每层的內容又是什么。

OSI七层模型

OSI(Open System Interconnection,开放系统互连)。七层网络模型被称为 开放式系统互连参考模型,这是一个逻辑上的定义和规范。

它把网络从逻辑上划分成了七层,每一层都有着相关和相对应的物理设备,如交换机、路由器等,其是一种 框架性的设计方法 ,主要功能是为了帮助不同类型的主机实现数据的传输。

它最大的优点就是将 服务、接口和协议这三个概念明确的区分开来,通过七个层次化的结构模型使得不同的系统不同的网络之间可以实现可靠的通讯。

七个层次,每个层次都有特定的功能和责任,这种设计可以 使得网络设计和实现更加模块化和可控 ,不同层级之间更加独立,方便扩展和更新,可以根据不同层级的功能快速定位出现的 错误和问题。并且OSI七层模型是ISO组织制定的一种描述网络协议和服务的标准。

     但是在实际的软件网络服务开发中,如果完全按照上述的OSI七层模型进行开发,事实上是不方便的。由于制定标准和实际开发的不是同一批人,实际开发中的具体情况是不可能在制定标准时就考虑到位的。如会话层,会话层主要负责 通信在何时建立、何时断开的问题,但是在实际情况中,通信的建立和断开绝大多数就是依照具体的业务来决定的。底层的协议是做不到对上层业务的完全支持的。还有表示层和应用层,由于业务的不同,表示层的数据转换也是不固定的。应用层所使用的特定的协议也是多种多样的。

    类似上面提到的三层的协议在操作系统的底层是不能非常统一地实现的,所以 操作系统底层中协议一般包含网络层和传输层。

    数据链路层则是由驱动进行支持,上三层的协议是业务开发时,具体设计的协议。

    所以在实际开发中,我们反而使用的是另一种模型:TCP/IP 五层(四层)模型。 

TCP/IP 五层(四层)模型

 TCP/IP是一组协议的代名词,它包含了许多的协议,组成了TCP/IP协议簇

TCP/IP通讯协议采用了5层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。

  • 物理层: 负责光/电信号的传递方式. 比如现在以太网通用的网线(双绞 线)、早期以太网采用的的同轴电缆(现在主要用于有线电视)、光纤, 现在的wifi无线网使用电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等. 集线器(Hub)工作在物理层.
  • 数据链路层: 负责设备之间的数据帧的传送和识别. 例如网卡设备的驱动、帧同步(就是说从网线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就自动重发)、数据差错校验等工作. 有以太网、令牌环网, 无线LAN等标准. 交换机(Switch)工作在数据链路层.
  • 网络层: 负责地址管理和路由选择. 例如在IP协议中, 通过IP地址来标识一台主机, 并通过路由表的方式规划出两台主机之间的数据传输的线路(路由). 路由器(Router)工作在网路层.
  • 传输层: 负责两台主机之间的数据传输. 如传输控制协议 (TCP), 能够确保数据可靠的从源主机发送到目标主机.
  • 应用层: 负责应用程序间沟通,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等. 我们的网络编程主要就是针对应用.

即使TCP/IP网络协议栈是5层的,但是也可以对应OSI七层模型:

由于在一般的网络开发情况下,物理层考虑的较少,因此很多时候也可以称为 TCP/IP四层模型。

一般情况下:

  • 主机,它的操作系统内核实现了 传输层到物理层的内容。
  • 路由器,它实现了网络层到物理层。
  • 交换机,它实现了从数据链路层到物理层。
  • 集线器,他只实现了物理层。 

上面所提到的并不绝对,如很多交换机也实现了网络层的转发;很多路由器也实现了部分传输层的內容。

TCP/IP网络协议栈和操作系统的关系

它们之间的关系可以由下面的这张图简单概括

这张图表明了在操作系统内核中是包含着传输层和网络层的协议的。在驱动程序中是包含着数据链路层的协议的。在硬件中,是包含着物理层的协议的。

应用层的协议就是开发时和用户使用时需要使用到的协议了,并且从传输层到用户层,操作系统是提供有 系统调用 进行操作的。

总结起来就是,TCP/IP协议是操作系统的一个模块,网络协议栈实际上是隶属于操作系统的。并且从硬件到操作系统对应的层级中,由于硬件的不同、驱动的不同、操作系统内核的不同,其包含的协议模块也不尽相同。但是尽管不同平台协议实现的细节是不同的,但是依旧需要使用这样的标准将TCP/IP协议实现起来,以保证不同的平台之间使用相同的标准进行通信。


接下来看看不同平台之间的通信大概是什么样的。

首先是用户产生网络信息,需要通过网络发送到另外一个平台的用户。

  1. 用户产生网络信息,通过应用层协议,然后穿过整个网络协议栈,到达当前网络平台的物理层。
  2. 再经过网络转发,被对方的物理层接受到,然后再提交到对方的数据链路层,一直向上提交,最终到达对方的应用层,然后被对方用户接收到。

整个的过程大概是这个样子的,我们假设存在两个TCP/IP网络协议标准的平台,Windows发送,Linux接收,对应的流程用以下的图片描述:

两个主机之间通过网络通信的简单流程大概就是上述这样的,用户产生的数据包(信息)的流向在主机内都是自顶向下或者自底向上的,这是为什么呢?

      因为网络通信的数据包的传递是通过硬件实现的,如果是用户产生的数据,不能一下子就传输到指定的硬件,所以就需要从用户层传输到硬件上,所以发送数据包的流向就是自顶向下,接受数据包时就是自底向上。

      且目前的所有的I/O操作都是这样的。


数据包在整个的传输过程中会经过不同的层级,但是在用户看来,其实就只是一对一的通信而已。因为用户是看不到数据包在向下层传输的过程的,事实上,每一个层级都是看不到其下层的传输过程的。即同层协议都只认为自己在和对方同层的直接进行通信。

再次理解网络协议栈

我们之前提到过“协议”就是一种约定,但是在计算机中该如何体现呢?

    体现在代码逻辑、数据上面。

下面再举一个生活中的例子:网购

我们在网上买东西的时候,并不是像在超市购物一样,看上什么直接买就可以。而是需要经历好多个步骤。

  1. 商家首先对售出的商品进行打包,然后给到快递公司。
  2. 快递公司进行二次包装,在进行二次包装的时候还需要添加一些额外的信息,如快递单号、发件信息、收件信息等。这些信息并不是给买家看的,而是在快递运输时使用的。
  3. 商品经历一些运输到达买家手中。
  4. 买家拿到的并不单单是一个商品,其中还包含着许多的信息,只不过这些信息不需要买家去关注而已。

这个网购的过程实际上就是反了不同主机之间通过网络协议栈进行数据通信的过程。商家和买家就可以看作是两台主机的用户,快递公司可以看作网络协议栈。

  • 快递在运输过程中会包含多种快递信息,这些实际上并不是给买家看的,而是给快递公司内部和快递员看的,快递单上的数据就可以看作是快递公司内部和快递员之间的协议。这一点也反映了在实际的网络通信中,为了维护被传输的数据,实际是需要在原数据的基础上添加其他数据(协议数据)的,这是协议在数据上的体现。
  • 同层协议则认为自己是在与对方一对一通信,就像商家与买家直接交流,只要快递正常运输最终能到达,中间的过程和信息双方是不在乎的,这也就是说协议数据实际上是为了同层级通信而添加的。
  • 协议数据是为了同层级的通信,那么同层级就需要都能读取协议数据,那么每一个层级都需要制定自己的协议,进而根据协议来添加同层级可以读取的协议数据。
  • 快递公司和快递员是根据快递单上的数据来运输商品,这反映了实际的网络通信中,被传输的数据会根据协议数据,通过设定、编写的代码逻辑在不同的主机之间进行传输,这是协议在代码逻辑上的体现。

总结一下网络协议栈,我们可以得到三个结论:

  1. 数据包在主机内是自顶向下或者自下向上流动的
  2. 同层协议都认为自己在和对方直接通信,每一个层级都需要制定自己的协议
  3. 为了维护被传输的数据,在实际的网络通信中,是需要在原数据的基础上添加其他数据的。

下面我们详细了解一下两个主机之间的通信过程

  1. 首先发送端主机产生的数据在本主机内部是自上而下流动的。
  2. 在传输过程中不同层会在接收到上层的数据包之后在基础上再添加本层的协议数据,这部分数据是拼接在原始数据的开头部分的。 每层添加的这部分协议数据被称为 报头,即不同层会为其收到的数据包添加本层的报头,该过程被称为对数据进行封装的过程。
  3. 接着发送端主机是将数据包通过物理层传输到接收端主机的物理层的。
  4. 接收端主机物理层接收到数据之后,数据包在其中是自底向上流动的。
  5. 在流动过程中,当前层会将发送方对应层添加的协议数据(报头)进行分析、解包,然后将解包后的数据向上层传输。该动作就可以看作是同层协议与对方直接通信,因为对应层只会针对相应的报头进行解包。
  6. 最终经过一层层传输到达接收方用户。

局域网内计算机通信原理 

局域网是对于较小的地理范围内所建立的一组相互连接的计算机和网络设备的集合,也被称为以太网。

下面举个生活中的例子来类比一下局域网中的计算机通信过程。

假设在一个课堂中,学生和老师的名字都是唯一的。老师点到一位同学的名字,这位同学可以听到并作出回答。这个过程中,班级里的所有人都可以听到老师点的这位同学的名字,但是其他同学并没有回应老师,这是因为他们知道老师叫的不是自己。

还要考虑到这么一种情况,班级里的人是可以随意说话的,当班级里的秩序十分混乱的时候,大家都在各说各话,被点名的同学可能就会因为听不到老师的点名从而无法回应。

上面例子中的某些现象可以类比局域网通信时候的一些现象:

首先,我们先了解一个概念:MAC地址 

MAC地址 是 识别网络中物理网络设备的唯一标识符. 所有物理网络设备的MAC地址在全球范围内都是唯一的.属于数据链路层,而IP地址属于网络层

MAC地址由一个48位的二进制数字组成, 一般表现为 12位的十六进制数。

查看windows的MAC地址:打开Windows Powershell或者CMD,执行 ipconfig /all命令

查看Linux的MAC地址 :执行ifconfig命令

每台可以连接到网络的主机都要有一个唯一的标识符,这个标识符就是主机中 物理网络设备的MAC物理地址 物理网络设备的MAC地址是全球唯一的

  • 所以整个班级就可以看作是一个局域网,每个学生和老师都可以看做是该局域网内的主机,学生和老师的名字就可以看作是局域网内部每个主机的MAC地址。
  • 班级里老师找学生回答问题实际上就是在寻找学生的“MAC地址”,找到了,学生就可以回答问题。
  • 一个局域网中的任意一台主机,都是可以在任意时刻发送消息的。如果出现许多主机同时发送消息,那么就可能非常混乱,导致主机间的互相干扰,进而扰乱通信。我们将这种现象称为 碰撞,并将可能发生碰撞的一部分主机、设备称为 碰撞域。就像班级里乱哄哄的,导致需要传达的信息被干扰,最后无法回应。

那么出现了碰撞该如何解决呢?

可以在通信前进行碰撞检测,检测是否有其他主机已经在通信,如果有就进行 碰撞避免,等待其他主机不通信了,再进行通信。


局域网通信的简单原理图

即负责发送和接收数据的主机,分别需要向以太网中发送和获取数据,且在发送数据之前还要在以太网中检测是否可能发生碰撞。也就是说,以太网中的不同主机都是可以看到以太网的,从系统角度来看待以太网的话,他就是一个临界资源。 

不同局域网间计算机的通信原理

那么不同局域网之间该如何通信呢?

当局域网一的某台主机需要向局域网二的某台主机发送信息时,局域网一主机对数据的封装过程和局域网二主机对数据的解包过程与局域网内部通信时两台主机对数据包的封装和解包过程是一样的。

不同的是封装完的数据包转发的过程,局域网内部通信时,数据包可以直接在局域网上转发到其他主机。而不同的局域网之间的主机想要进行通信需要通过路由器的转发。

路由器每连接一个局域网就可以看作是此局域网内的一个主机。

下图中路由器连接了两个局域网,也就是说路由器可以分别和局域网一内的主机和局域网二内的主机直接通信。那么想要两个局域网之间进行通信就可以将数据包传输给路由器,再由路由器传输给另一个局域网中的目标主机。

总结一下局域网之间通信的步骤:

  1. 局域网一的主机, 将封装完毕的数据包 通过 以太网 直接发送给路由器
  2. 路由器 将以太网协议数据 进行解包, 然后 向上传输到路由器自身的IP层
  3. 再将数据包向下传输到路由器自身的数据链路层, 添加局域网二数据链路层协议的协议数据 封装数据包
  4. 然后 再将封装好的数据包 直接传输到 局域网二的目标主机

那么思考一个问题,在同一个局域网内不同的主机间我们可以通过设备的MAC地址进行通信,但是对于不同的局域网之间我们却需要通过IP地址进行通信这是为什么?

      因为不同主机间的网络设备的MAC地址是杂乱无章的,而同一局域网下的主机的ip地址通常是在一个子网范围内的,路由器就可以通过IP判断将接收到的数据包向哪一个局域网转发。

例如,局域网一的IP为 IPA,局域网二的IP为 IPB,那么路由器在接收到数据包后,可以通过目标IP(IPB),将数据包转发到子网范围包括目标IP的局域网二中。

从上面我们可以发现,从IP层往上(包含IP层)发送的主机和接收的主机看到的数据是一摸一样的。即网关设备会对数据链路层的协议报头进行解包、封装,但是不会对更上层的数据进行改动。所以网络也被称为 IP网络。

 数据包的封装

我们在对上述的网络通信原理作简单介绍时,例子中主机内部的协议都是指定的,即

但是实际上我们前面也提到了对于不同的主机不同的层级所使用的协议也是不尽相同的例如:

  1. 应用层:tfp、http、https...
  2. 传输层:tcp、udp、ICMP...
  3. 网络层:ip、arp、rarp... 

且接收主机在解包时是需要将数据包向上传递的,那么接收主机如何确定要将有效载荷交付给上层的哪一个协议呢?(有效载荷:解包后,需要向上层交付的数据包的內容)

    事实上,需要的交付信息在解包时就已经获取到了,其实,发送主机在封装报头的时候,就需要考虑到未来解包时,将自己的有效载荷交付给上层的哪一个协议。这个过程被称为 有效载荷的分用。


总结:

  1. 一般而言,任何报头属性里面,一定需要存在一些字段以支持封装和解包。即报头中一定要存在描述 数据包哪部分是报头,哪部分是有效载荷的字段。
  2. 一般而言,任何报头属性里面,一定需要存在一些字段以支持分用,即一定要存在一些描述有效载荷需要交付给上层哪一个协议的一些字段。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词