Linux_初识网络协议

  • 网络协议
  • 数据传输

发明计算机的目的是为了计算数据,结果有可能自己用,也有可能交给其他人使用,所以就需要多台计算机之间可以互相通信。按照通信距离,计算机网络大体分为:局域网(LAN)和广域网(WAN)。
如果两台计算机距离较近,那么直接用一根网线相连即可完成通信。但如果两台计算机之间的距离较远,那么在通信的过程中就无法避免的产生如下问题:

  1. 一台计算机如何找到另一台计算机
  2. 数据如何发送,如果有多条路径,怎么选择路径
  3. 数据在传输的过程中是否会出现丢失

两台计算机之间通信的关键就要解决上述问题,怎么解决呢?协议的定制就是为了解决通信过程中遇到的一系列问题。

一.网络协议

1.1 什么是协议

网络协议为计算机网络中进行数据交换而建立的规则、标准或约定的集合。说白了,协议就是通信双方的约定,建立协议是为了减少后期的沟通成本,提高通信效率,解决通信问题。比如购房时签订了协议,有了这份协议在发生纠纷时就很容易解决。

  • 在Linux中,协议就是一个c程序(软件)。
1.2 协议分层

怎样定制协议才能做到效率最大化呢?众所周知,在计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。我们将在计算机通信中遇到的问题分类,每一类问题对应一层协议,不同协议按照顺序分为上下层关系,上层使用下层提供的接口来访问下层。每一层只需要关注自己同层的功能;当一层协议出现问题时,不会影响其他层协议。这样就做到了高内聚低耦合。
类比打电话:用户只认为和同层用户进行通信,不管用户用的什么语言(中文,英语),通信双方都能听懂,而手机也认为它和对面的那台手机通信,当手机换位电脑,仍然不会影响上层用户的通信,这就是用户层和下层功能上的解耦。
image.png

1.3 OSI七层协议模型

七层模型,亦称OSI(Open System Interconnection)参考模型,是参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系。它是一个七层的、抽象的模型,不仅包括一系列抽象的术语或概念,也包括具体的协议。
image.png
image.png
由于OSI七层协议模型比较复杂,TCP/IP协议模型在此基础上诞生。

1.4 TCP/IP协议模型

TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCPIP两个协议,而是指一个由FTPSMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。

  • TCP/IP协议中的应用层里面包含了OSI七层协议模型中的应用层、表示层、会话层
  • 上层使用下层提供的接口

image.png

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

TCP/IP协议模型在计算机系统中的位置,如下图:
image.png
应用层在用户层实现,传输层和网络层在操作系统层实现,数据链路层在驱动层实现,物理层在硬件层实现。数据从网络中发来,由网卡接收,然后逐层向上传递到应用层,由应用程序使用数据处理任务。
在Linux中**一切皆文件,**因此网卡也可以看作是文件,虽然我们还没有见到网络的接口,但我们可以预知,应用层对于网络的访问,必定要创建文件描述符,然后通过文件描述符读写数据。
那么为什么网络单独创建了一系列系统调用接口, 而不是挂接到文件管理呢?前面提到许多操作系统有可能在实现系统部分有所差异,但是在实现网络部分,它们一定是一样的,所以操作系统单独为网络设计了一系列系统调用接口。注意:这里的一致性体现在操作系统层,对于数据链路层和物理层,取决于硬件厂商。

二.数据传输

在计算机中一切服务都是以进程的方式运行的,两台计算机之间互相通信,本质就是两台计算机上的进程在通信。

  • 发送进程:用户输入数据,数据自顶向下,逐层传递到物理层(网卡),经由网卡发送到网络中,待接收进程接收
  • 接收进程:识别到该消息是给自己的,然后数据逐层向上传递到应用层,最后交付给用户。
2.1 局域网中数据的传输

有效载荷(数据)每到一层都要封装对应的协议报头,然后向下交付,以待对端接收。
image.png
数据从用户A出发,逐层向下封装,然后传到用户B的数据链路层。每层根据自己的协议报头,将报文解包并且将有效载荷向上传递给指定协议。
局域网通信原理:以太网
一个局域网中可能有多台计算机,当一台计算机发送消息时,所有计算机都能收到这条消息。当发送方的有效载荷到达数据链路层时,数据链路层的协议会添加协议报头,这个报头中有目的MAC地址,如果接收方的数据链路层检测到该MAC地址不是自己,就会丢弃该数据。
image.png

  • 抓包工具的原理就是任何数据都接收。

一个局域网中,任何时刻都可能有多台计算机发送消息,这时候多个消息就会形成碰撞,导致消息异常。因此,数据链路层要保证每个时刻都只有一个人发消息。

MAC地址

  • MAC地址用来识别数据链路层中相连的节点;
  • 长度为48位, 及6个字节. 一般用16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19)
  • 在网卡出厂时就确定了, 不能修改. mac地址通常是唯一的(虚拟机中的mac地址不是真实的mac地址, 可能会冲突; 也有些网卡支持用户配置mac地址).

2.2 跨一台路由器的网络中数据传输

路由器:工作在网络层的设备,具备网络层以下的所有功能。可以将路由器看作一个主机(节点)。
image.png

在互联网中,公网IP地址可以唯一标定一个主机。在网络通信中,必须要知道对端IP地址。

IP协议有两个版本, IPv4和IPv6。我们主要讨论IPv4地址

  • IP地址是在IP协议中, 用来标识网络中不同主机的地址;
  • 对于IPv4来说, IP地址是一个4字节, 32位的整数;
  • 我们通常也使用 “点分十进制” 的字符串表示IP地址, 例如 192.168.0.1 ; 用点分割的每一个数字表示一个字节, 范围是 0 - 255;

当发送方封装的数据到达网络层时,会在网络层的路由表中检测当前局域网内有无目的IP地址,若没有,则会在数据链路层的报头中,添加路由器的MAC地址,将该数据发送到路由器中,经由路由器转发到其他局域网内。可以看到,在不同的局域网中,两台主机仍然可以通信,这是因为网络层屏蔽了下层的差异。

  • 27
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这道题目是要求我们实现链表的基本操作,包括创建链表、插入节点、删除节点、遍历链表等。以下是一个简单的链表实现代码示例: ```c++ #include <iostream> using namespace std; // 定义链表节点结构体 struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; // 创建链表 ListNode* createList(int nums[], int n) { if (n == 0) return NULL; ListNode *head = new ListNode(nums[0]); ListNode *cur = head; for (int i = 1; i < n; i++) { cur->next = new ListNode(nums[i]); cur = cur->next; } return head; } // 插入节点 void insertNode(ListNode *&head, int pos, int val) { if (pos < 0) return; if (pos == 0) { ListNode *newNode = new ListNode(val); newNode->next = head; head = newNode; return; } ListNode *cur = head; while (cur && pos > 1) { cur = cur->next; pos--; } if (cur) { ListNode *newNode = new ListNode(val); newNode->next = cur->next; cur->next = newNode; } } // 删除节点 void deleteNode(ListNode *&head, int pos) { if (pos < 0) return; if (pos == 0) { ListNode *delNode = head; head = head->next; delete delNode; return; } ListNode *cur = head; while (cur && pos > 1) { cur = cur->next; pos--; } if (cur && cur->next) { ListNode *delNode = cur->next; cur->next = delNode->next; delete delNode; } } // 遍历链表 void traverseList(ListNode *head) { while (head) { cout << head->val << " "; head = head->next; } cout << endl; } int main() { int nums[] = {1, 2, 3, 4, 5}; int n = sizeof(nums) / sizeof(int); ListNode *head = createList(nums, n); traverseList(head); insertNode(head, 2, 6); traverseList(head); deleteNode(head, 3); traverseList(head); return 0; } ``` 在上面的代码中,我们定义了一个 `ListNode` 结构体作为链表节点,包括节点值 `val` 和指向下一个节点的指针 `next`。同时,我们实现了创建链表、插入节点、删除节点和遍历链表等基本操作。在使用链表时,我们可以先通过 `createList` 函数创建一个链表,然后对链表进行插入、删除和遍历操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值