UDP的多点通信

news2024/9/21 18:58:02

文章目录

  • 一. 网络属性
  • 二. 多点通信
    • **2.1. 单播**
    • 2.2. 广播
      • 2.2.1 广播的发送端流程 (类似UDP客户端)
      • 2.2.2 广播的接收端流程(类似UDP服务器)
    • 2.3. 组播
      • 2.3.1组播的发送端流程 (类似UDP客户端)
      • 2.3.2组播的接收端流程(类似UDP服务器)
      • 2.3.3 加入多播组
      • 示例代码

一. 网络属性

setsockopt / getsockopt(设置/获取网络属性)

功能:设置/获取网络属性;
原型:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname,
void *optval, socklen_t *optlen);
       int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);

参数:

  • int sockfd:指定要设置/获取 哪个套接字的属性;

  • int level:指定要控制的协议层次;
    SOL_SOCKET:应用层 通用套接字选项; man 7 socket
    IPPROTO_TCP:TCP选项 man 7 TCP
    IPPROTO_UDP:UDP选项 man 7 UDP
    IPPROTO_IP:IP选项; man 7 IP

  • int optname:指定要控制的内容,指定控制方式;
    — SOL_SOCKET: man 7 socket -----
    SO_REUSEADDR:允许端口快速重用 optval: int*
    SO_BROADCAST:允许广播 optval: int*
    SO_RCVBUF/SO_SNDBUF:接收缓冲区 发送缓冲区大小
    SO_RCVTIMEO/SO_SNDTIMEO:接收超时时间,发送超时时间

  • void *optval:根据optname不同,该类型不同;

  • socklen_t optlen/socklen_t *optlen:真实的optval指针指向的内存空间的大小;

返回值:

  • 成功,返回0;
  • 失败,返回-1,更新errno;

image-20230412130510811

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
    int sfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sfd < 0)
    {
        perror("socket");
        return -1;
    }

    //设置允许广播
    int broad = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &broad, sizeof(broad)) < 0)
    {
        perror("setsockopt");
        return -1;
    }
    printf("设置允许广播成功\n");


    //判断默认是否允许广播
    broad = 100;
    socklen_t optlen = sizeof(broad);
    if(getsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &broad, &optlen) < 0)
    {
        perror("getsockopt");
        return -1;
    }
    printf("broad = %d\n", broad);


    close(sfd);                                                              
    return 0;
}

二. 多点通信

2.1. 单播

  1. 主机之间一对一的通信模式,交换机以及路由器对数据只进行转发,不做复制
  2. 每次只有两个实体相互通信,发送端和接收端都是唯一确定的。

2.2. 广播

  1. 主机之间 一对多 的通信模式,网络对其中的每一台主机发出的信息都进行无条件复制并转发。

  2. 所有主机都可以接收到广播信息(不管你是否需要)

  3. 禁止广播数据穿过:路由器(只能做局域网内通信),防止广播数据影响大面积主机。

  4. 只有UDP能广播。

  5. 广播地址:有效网络号 + 全是1的主机号

    1. 192.168.8.123 —> 192.168.8.255
    2. 255.255.255.255:给所有网段中的所有主机发送广播,但是无法穿过路由器,所以只能做局域网内通信。

2.2.1 广播的发送端流程 (类似UDP客户端)

  1. socket 创建套接字

  2. setsockopt 设置允许广播,默认是不允许的

  3. bind 非必须绑定

  4. 填充接收方的地址信息结构体,给sendto函数使用,指定发给谁

    1. IP:填广播IP,(192.168.8.255 )
    2. PORT:与接收方绑定的一致,
  5. sendto 发送数据

示例代码:

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define ERR_MSG(msg) do{\
    fprintf(stderr, "line:%d ", __LINE__);\
    perror(msg);\
}while(0)

#define SER_IP "192.168.0.255"   //广播IP ifconfig
#define SER_PORT 6666           //1024-49151

int main(int argc, const char *argv[])
{
    //创建报式套接字
    int cfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(cfd < 0)
    {
        ERR_MSG("socket");
        return -1;                                                                   
    }

    //设置允许广播
    int broad = 1;
    if(setsockopt(cfd, SOL_SOCKET, SO_BROADCAST, &broad, sizeof(broad)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("set broadcast success\n");

    //bind  非必须绑定
    //如果不绑定则由操作系统自动绑定IP和端口


    //填充接收方的地址信息结构体,给sendto函数使用
    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;              //必须填AF_INET;
    sin.sin_port        = htons(SER_PORT);      //端口号的网络字节序
    sin.sin_addr.s_addr = inet_addr(SER_IP);    //广播IP地址

    struct sockaddr_in rcvaddr;     //存储数据包是从谁哪里来的
    socklen_t addrlen = sizeof(rcvaddr);

    char buf[128] = "";
    ssize_t res = 0;
    while(1)
    {
        bzero(buf, sizeof(buf));
        printf("请输入>>> ");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf)-1] = 0;

        //发送数据,发送给服务器
        if(sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }
        printf("发送成功\n");
    }

    //关闭文件描述符
    close(cfd);
    return 0;
}

2.2.2 广播的接收端流程(类似UDP服务器)

  1. socket 创建套接字

  2. 填充接收自身的地址信息结构体,给bind函数使用

    1. IP :广播IP(192.168.8.255 或者 0.0.0.0(INADDR_ANY))

      1. 0.0.0.0:将本机所有可用IP都绑定到套接字上,192.168.8.123, 127.0.0.1(本地环回),广播IP,组播IP
    2. PORT :1024-49151

  3. bind 必须绑定

  4. recvfrom 接收广播数据

接收方:

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define ERR_MSG(msg) do{\
    fprintf(stderr, "line:%d ", __LINE__);\
    perror(msg);\
}while(0)

#define IP "192.168.0.255"   //广播IP ifconfig
#define PORT 6666           //1024-49151

int main(int argc, const char *argv[])
{
    //创建报式套接字                                                                          
    int sfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }

    //填充接收方自身的地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;          //必须填AF_INET;
    sin.sin_port        = htons(PORT);      //端口号的网络字节序
    sin.sin_addr.s_addr = inet_addr(IP);    //广播IP地址

    //绑定 必须绑定
    if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }

    struct sockaddr_in cin;     //存储数据包是从谁哪里来的
    socklen_t addrlen = sizeof(cin);

    char buf[128] = "";
    ssize_t res = 0;
    while(1)
    {
        bzero(buf, sizeof(buf));
        //接收数据,必须接收数据包的发送方地址信息,给sendto使用
        res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen);
        //res = recv(sfd, buf, sizeof(buf), 0);
        if(res < 0)
        {
            ERR_MSG("recvfrom");
            return -1;
        }
        printf("[%s : %d]: %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
    }

    //关闭文件描述符
    close(sfd);
    return 0;
}

2.3. 组播

  1. 广播方式是给同一网段下的所有主机发送信息,会占用大量网络带宽,影响正常通信。
  2. 主机之间一对一组的通信模式,也就是加入了同一个小组的主机可以收到此组内的所有数据。
  3. 组播地址:D类:224.0.0.0-239.255.255.255

2.3.1组播的发送端流程 (类似UDP客户端)

  1. socket 创建套接字
  2. bind 非必须绑定
  3. 填充接收方的地址信息结构体,给sendto函数使用,指定发给谁
    1. IP:填组播IP,(224.0.0.0-239.255.255.255 ),与接收方绑定的组播IP一致。
    2. PORT:与接收方绑定的一致,
  1. sendto 发送数据

2.3.2组播的接收端流程(类似UDP服务器)

  1. socket 创建套接字

  2. setsockopt 加入多播组:level:IPPROTO_IP optname:IP_ADD_MEMBERSHIP optval:struct ip_mreqn*

    1. 注意加入的多播组IP,与下面绑定的组播IP一致
  3. 填充接收自身的地址信息结构体,给bind函数使用

    1. IP :组播IP( 224.0.0.0-239.255.255.255 或者 0.0.0.0 )

      1. 0.0.0.0:将本机所有可用IP都绑定到套接字上,192.168.8.123, 127.0.0.1(本地环回),广播IP,组播IP
    2. PORT :1024-49151

  4. bind 必须绑定

  5. recvfrom 接收广播数据

2.3.3 加入多播组

功能:设置/获取网络属性;
原型:
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
参数:
    int sockfd:指定要设置/获取哪个套接字的属性;
    int level:指定要控制的协议层次;
        IPPROTO_IP:IP选项;                man 7 IP
        
    int optname:指定要控制的内容,指定控制方式;
      --- IPPROTO_IP:IP选项;                man 7 IP -----
         IP_ADD_MEMBERSHIP:加入多播组

    void *optval:根据optname不同,该类型不同;
            struct ip_mreqn {
               struct in_addr imr_multiaddr; /* IP multicast group
 address */    组播IP的网络字节序,
               struct in_addr imr_address;   /* IP address of local
 interface */ 本机IP的网络字节序,ifconfig
               int            imr_ifindex;   /* interface index */     设备索引号,网卡编号
                                                                   1. 0,默认索引号
                                                                   2. ifconfig查看网卡名,例如ens33.
                                                                       ip ad,找到ens33对应的编号为2
                                                                   3. if_nametoindex("ens33")                                                                                                                                             
           };

            struct ip_mreq  {
                struct in_addr imr_multiaddr;   /* IP multicast address of group */
                struct in_addr imr_interface;   /* local IP address of interface */
            };

    socklen_t optlen/socklen_t *optlen:真实的optval指针指向的内存空间的大小;
返回值:
    成功,返回0;
    失败,返回-1,更新errno;

image-20230412214223006

示例代码

  1. 发送方

    #include <stdio.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    
    #define ERR_MSG(msg) do{\
        fprintf(stderr, "line:%d ", __LINE__);\
        perror(msg);\
    }while(0)
    
    #define GRP_IP "224.1.2.3"   //224.0.0.0-239.255.255.255
    #define PORT 6666           //1024-49151
    
    int main(int argc, const char *argv[])
    {
        //创建报式套接字
        int cfd = socket(AF_INET, SOCK_DGRAM, 0); 
        if(cfd < 0)
        {   
            ERR_MSG("socket");
            return -1; 
        }   
                                                                                         
        //bind  非必须绑定
        //如果不绑定则由操作系统自动绑定IP和端口
    
    
        //填充接收放的地址信息结构体,给sendto函数使用
        struct sockaddr_in sin;
        sin.sin_family      = AF_INET;              //必须填AF_INET;
        sin.sin_port        = htons(PORT);          //端口号的网络字节序
        sin.sin_addr.s_addr = inet_addr(GRP_IP);    //IP地址
        
        char buf[128] = ""; 
        ssize_t res = 0;
        while(1)
        {   
            bzero(buf, sizeof(buf));
            printf("请输入>>> ");
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf)-1] = 0;
    
            //发送数据,发送给服务器
            if(sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
            {
                ERR_MSG("sendto");
                return -1; 
            }
            printf("发送成功\n");
    
        }   
    
        //关闭文件描述符
        close(cfd);
        return 0;
    }
    
    1. 接收方

      #include <stdio.h>
      #include <sys/stat.h>
      #include <sys/types.h>
      #include <unistd.h>
      #include <sys/socket.h>
      #include <netinet/in.h>
      #include <arpa/inet.h>
      #include <string.h>
      
      #define ERR_MSG(msg) do{\
          fprintf(stderr, "line:%d ", __LINE__);\
          perror(msg);\
      }while(0)
      
      #define IP     "192.168.0.119"   //本机IP ifconfig
      #define GRP_IP "224.1.2.3"      //组播IP 224.0.0.0 - 239.255.255.255
      
      #define PORT 6666           //1024-49151
      
      int main(int argc, const char *argv[])
      {
          //创建报式套接字
          int sfd = socket(AF_INET, SOCK_DGRAM, 0); 
          if(sfd < 0)
          {   
              ERR_MSG("socket");
              return -1; 
          }   
      
          //加入多播组                                                                        
          struct ip_mreqn mq; 
          mq.imr_multiaddr.s_addr = inet_addr(GRP_IP);    //组播IP
          mq.imr_address.s_addr   = inet_addr(IP);        //本机IP
          mq.imr_ifindex = 2;                             //设备索引号
      
          if(setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mq, sizeof(mq)) < 0)
          {   
              ERR_MSG("setsockopt");
              return -1; 
          }   
          printf("加入多播组成功\n");
      
          //填充接收放的地址信息结构体
          struct sockaddr_in sin;
          sin.sin_family      = AF_INET;              //必须填AF_INET;
          sin.sin_port        = htons(PORT);          //端口号的网络字节序
          sin.sin_addr.s_addr = inet_addr(GRP_IP);    //组播IP地址,与加入的组播IP一致
          
          //绑定 必须绑定
          if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
          {   
              ERR_MSG("bind");
              return -1; 
          }   
      
          struct sockaddr_in cin;     //存储数据包是从谁哪里来的
          socklen_t addrlen = sizeof(cin);
          
          char buf[128] = ""; 
          ssize_t res = 0;
          while(1)
          {   
              bzero(buf, sizeof(buf));
              //接收数据,必须接收数据包的发送方地址信息,给sendto使用
              res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen);
              if(res < 0)
              {
                  ERR_MSG("recvfrom");
                  return -1; 
              }
              printf("[%s : %d]: %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
      
          }   
      
          //关闭文件描述符
          close(sfd);
          return 0;
      }
      

      bzero(buf, sizeof(buf));
      //接收数据,必须接收数据包的发送方地址信息,给sendto使用
      res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen);
      if(res < 0)
      {
      ERR_MSG(“recvfrom”);
      return -1;
      }
      printf(“[%s : %d]: %s\n”, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);

      }   
      
      //关闭文件描述符
      close(sfd);
      return 0;
      

      }

      
      
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

对 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP 的实践

对 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP 的实践 前言 昨天编写了一篇博文: Activity启动模式与栈的使用小结&#xff0c;里面参考了下面这篇文章&#xff1a; Android面试官装逼失败之&#xff1a;Activity的启动模式 对里面关于 FLAG_ACTIVITY_CLEAR_TOP| F…

什么是开源?

从开源空间&#xff08;Open Source Space&#xff09;说起开源空间&#xff08;Open Source Space&#xff09;&#xff1a;一个边界封闭&#xff0c;内部开放的空间。在这个空间里&#xff0c;人们围绕数字公共产品&#xff08;服务&#xff09;&#xff0c;进行开放式协作。…

零售数据分析之操作篇13:图表联动分析

各位数据的朋友&#xff0c;大家好&#xff0c;我是老周道数据&#xff0c;和你一起&#xff0c;用常人思维数据分析&#xff0c;通过数据讲故事。 上期回顾与作业讲解 上一讲讲了子查询的应用场景&#xff0c;即有一个结果集&#xff08;ds2&#xff09;的筛选条件是来自另外…

【C++】继承---上(继承的引入及使用详解、切片赋值和作用域)

前言&#xff1a; 我们在学习C的第一节课就了解到C是一门面向对象的语言&#xff0c;面向对象的语言有三大特性&#xff1a; 封装、继承、多态 此前我们学习了封装&#xff0c;比如模拟实现vector&#xff0c;string或者迭代器等&#xff0c;不仅有利于我们的维护和管理&#…

【uniapp】Vue3版本项目出现Proxy代理对象无法正常取值问题解决

习惯了使用Vue2版本的uniapp项目&#xff0c;直到后来想升级版本&#xff0c;改用Vue3版本就会遇到一些无法正常取值&#xff08;访问属性&#xff09;问题&#xff0c;其中最显著问题就是Proxy代理造成的 在我们用浏览器调试的时候&#xff0c;遇到如同下图这样&#xff0c;出…

Spring Boot 项目如何实现上传头像功能?

目录 设计思路 效果展示 ​编辑 分析 前后端交互接口 请求 响应 代码实现和详细注释 数据库设计 自定义资源映射 前后端交互 客户端开发 服务器开发 设计思路 效果展示 分析 实现这个功能只要弄清楚以下几点即可&#xff1a; 怎么将头像数据发送给服务器&#x…

九龙证券|服务器龙头获资金连续抢筹,尾盘主力抢筹前期大热门股

今天&#xff0c;核算机职业取得主力大手笔抢筹。 今天主力资金净流出53.89亿元&#xff0c;其间创业板净流出3.19亿元&#xff0c;沪深300成份股净流出7.61亿元。 申万一级职业中&#xff0c;今天有19个职业上涨&#xff0c;传媒职业接连两日均涨近5%&#xff0c;居首位&…

stm32当中GPIO输出知识点汇总(GPIO的八种模式及其原理)

一、GPIO工作模式. 1. 四种输入模式 GPIO_Mode_IN_FLOATING 浮空输入模式 GPIO_Mode_IPU 上拉输入模式 GPIO_Mode_IPD 下拉输入模式 GPIO_Mode_AIN 模拟输入模式 2. 四种输出模式 GPIO_Mode_Out_OD 开漏输出模式 GPIO_Mode_Out_PP 推挽输出模式 GPIO_Mod…

【剑指offer-C++】JZ79:判断是不是平衡二叉树

【剑指offer-C】JZ79&#xff1a;判断是不是平衡二叉树题目描述解题思路题目描述 描述&#xff1a;输入一棵节点数为 n 二叉树&#xff0c;判断该二叉树是否是平衡二叉树。 在这里&#xff0c;我们只需要考虑其平衡性&#xff0c;不需要考虑其是不是排序二叉树。 平衡二叉树…

Nginx实现负载均衡的多种方法演示

文章目录前言一、配置讲解1.1 轮询算法&#xff08;默认&#xff09;1.2 IP_HASH算法1.3 Weighted算法1.4 URL_HASH算法总结前言 Nginx是一款高性能的Web服务器和反向代理服务器,它具有占用内存小、并发处理能力强、稳定性高等优点&#xff0c;适用于高并发、高负载的Web应用场…

pandas之DataFrame基础

pandas之DataFrame基础1. DataFrame定义2. DataFrame的创建形式3. DataFrame的属性4. DataFrame的运算5. pandas访问相关操作5.1 使用 loc[]显示访问5.2 iloc[] 隐式访问5.3 总结6. 单层索引和多层级索引6.1 索引种类与使用6.2 索引相关设置6.3 索引构造6.4 索引访问6.5 索引变…

BGP选路实验(重点是各种策略)

实验拓扑 基础配置(完成IGP的配置) 首先完成各 个接口IP地址,环回接口地址等一些基本配置&#xff0c;实现直连之间的互相通信 在R4&#xff0c;R5上的配置类似 [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 192.168.1.1 24 [Huawei-GigabitEthernet0/0/0]int g0/0…

低代码是什么意思

此前&#xff0c;阿里云智能总裁张建锋曾在钉钉发布会上表示&#xff1a;“未来的软件开发一定是碎片化的&#xff0c;低代码开发将成为未来几年的行业关键词。”这句话表明了低代码在过去两年的火爆程度&#xff0c;预示着低代码有望成为软件领域的新风口。 那低代码是什么意…

chatgpt智能提效职场办公-excel表格6-6-6格式怎么设置(数字按照三个数字一组进行分隔)

chatgpt智能提效职场办公-excel表格6-6-6格式怎么设置&#xff08;数字按照三个数字一组进行分隔&#xff09; 作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 在Excel表格中设置6-6-…

移除元素(数组篇)

27. 移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中…

004:Mapbox GL设定不同的style,更换底图形态

第004个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中设定不同的style,更换底图形态 。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共70行)相关API参考:专栏目标示例效果

「业务架构」需求工程—需求规范(第3部分)

将用户和系统需求记录到文档中。需求规范它是将用户和系统需求写入文档的过程。需求应该是清晰的、容易理解的、完整的和一致的。在实践中&#xff0c;这是很难实现的&#xff0c;因为涉众以不同的方式解释需求&#xff0c;并且在需求中经常存在固有的冲突和不一致。正如我们之…

GraphInsight 拓扑图体验

蚂蚁数据可视化 | G6&#x1f4da;前言&#x1f4da;使用说明&#x1f4d5;数据规则节点的属性&#x1f4da;前言 蚂蚁数据可视化 G6 图可视化引擎是一个简单、易用、完备的图可视化引擎&#xff0c;它在高定制能力的基础上&#xff0c;提供了一系列设计优雅、便于使用的图可视…

1~3年的测试工程师薪资陷入了瓶颈期,如何突破自己实现涨薪?

对于技术人员而言&#xff0c;职业规划一般分为两个方向&#xff1a;做技术、做管理。进入软件测试行业的新人都会从最基础的执行开始&#xff0c;然后是基本的功能测试。 随后大家会根据个人职业发展来进一步细化&#xff0c;有的走管理路线&#xff0c;成为主管、经理、项目…

《操作系统》by李治军 | 实验3 - 系统调用

目录 一、实验内容 二、实验准备 1、系统调用的具体流程 &#xff08;一&#xff09;调用接口函数 API &#xff08;二&#xff09;触发 0x80 号中断 &#xff08;三&#xff09;跳转到 system_call 函数 &#xff08;四&#xff09;执行系统调用函数 sys_xxx 2、总结概…