【C语言】通过socket看系统调用过程

一、通过socket看系统调用过程

在Linux操作系统中,系统调用是用户空间与内核空间之间交互的一种方式。当一个应用程序需要执行操作系统级别的任务时,比如创建一个网络套接字(socket),它必须通过系统调用请求内核来执行这些操作。下面是通过`socket`系统调用从用户空间到内核空间再映射到内核源码的详细过程:

1. 用户空间的API调用:

   用户程序通常会调用glibc(GNU C库,Linux系统上的C标准库)提供的`socket`函数。这个函数定义通常在`<sys/socket.h>`头文件中。

 int sockfd = socket(AF_INET, SOCK_STREAM, 0);

2. 封装成系统调用:

   在glibc中,`socket`函数会封装成一个系统调用。系统调用是通知操作系统核心执行任务的一种机制。每个系统调用都有一个唯一的数字标识符。

   // glibc层面的封装,实际上会经过一些复杂的宏定义和内联函数处理int socket(int domain, int type, int protocol) {return syscall(SYS_socket, domain, type, protocol);}

3. 从用户空间到内核空间的切换:

   根据计算机的体系结构,在用户程序发起系统调用后,会通过一些机制(比如软件中断、陷阱指令或特定的系统调用指令)将控制权转移给内核。这通常涉及到一些寄存器设置系统调用号和参数,然后执行一个中断指令,例如在x86架构中的`int 0x80`或`syscall`指令。

4. 系统调用处理程序:

   内核内部有一个系统调用处理程序,这个处理程序根据传入的系统调用编号识别并分派对应的内核函数进行处理。在x86架构Linux系统中,系统调用入口点通常在`entry_64.s`汇编文件中找到。

5. 内核空间中的函数调用:

   内核将对应的系统调用号映射到具体的内核函数。在内核源码中,这个过程通过一张系统调用表完成,这张表把系统调用号映射到对应的处理函数。`socket`系统调用会最终映射到内核中的`sys_socket`函数。

   // 系统调用号到处理函数的映射可能在一个类似下面的结构中:// sys_socket函数可能在net/socket.c文件中定义SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) {return __sys_socket(family, type, protocol);}

6. 内核函数执行和返回:

   sys_socket会执行必要的操作来创建一个新的socket,这包括分配一个socket结构体并初始化它,以及任何与协议相关的设置。执行完毕后,系统调用处理程序将把结果(比如新创建的socket文件描述符或错误码)返回到用户程序。
以上描述了`socket`函数从用户空间到内核空间的调用过程。需要注意的是,在不同的操作系统、不同的体系结构和不同的内核版本中,这一过程的具体细节可能会有所不同。 

二、EXPORT_SYMBOL(sock_create)/EXPORT_SYMBOL(sock_create_kern)

int sock_create(int family, int type, int protocol, struct socket **res)
{return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
}
EXPORT_SYMBOL(sock_create);
int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
{return __sock_create(net, family, type, protocol, res, 1);
}
EXPORT_SYMBOL(sock_create_kern);

在Linux内核中,`sock_create`和`sock_create_kern`函数是用于创建一个新的socket的函数。虽然一个是专为用户空间设计(sock_create),而另一个是专为内核空间设计(sock_create_kern),但它们都最终调用`__sock_create`函数来执行创建socket的实际工作。
下面是每个函数的目的:
1. sock_create:这个函数主要用于用户空间的请求来创建一个新的socket。它接受参数`family`(例如,AF_INET表示IPv4协议),`type`(例如,SOCK_STREAM表示流式套接字),和`protocol`(具体的协议,如TCP或UDP),它还需要一个指向socket结构体指针的指针`res`来存储新创建的socket。`sock_create`通过进程的`nsproxy`字段中的网络命名空间(net_ns)来调用`__sock_create`,并且将 user 标志设置为0,表示这一创建操作来自用户空间。
2. sock_create_kern:与`sock_create`相似,`sock_create_kern`被用于内核空间的socket创建。它也需要相同类型的参数,但是不同的是它接收一个网络命名空间`net`的指针作为其第一个参数,表示socket将属于该网络命名空间,还将`user`标志设置为1,表示这一创建操作来自内核空间。
3. EXPORT_SYMBOL宏:它用于将函数导出,以便这些函数可以被内核的其他模块调用。例如,如果一个内核模块想要创建一个socket,它可以调用`sock_create`或者`sock_create_kern`,前提是这个模块与这些函数定义在同一个内核编译范围内。
最终的创建工作是通过调用`__sock_create`来完成的,它是一个内部函数,不直接暴露给用户空间或其他内核模块。`__sock_create`实际上负责在给定的网络命名空间、地址族、socket类型和协议下分配和初始化一个新的socket。
这是一个非常简化的说明,真正的socket创建过程涉及更多的步骤,例如,分配内存给新的socket,初始化socket结构,以及可能将socket与某些数据结构相关联等等。 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【服务器数据恢复】服务器RAID模块硬件损坏的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 某品牌服务器中有一组由数块SAS硬盘组建的RAID5磁盘阵列&#xff0c;服务器操作系统是WINDOWS SERVER&#xff0c;服务器中存放企业数据&#xff0c;无数据库文件。 服务器出故障之前出现过几次意外断电的情况&#xff0c;服务器断电…

用HTML5实现灯笼效果

本文介绍了两种实现效果&#xff1a;一种使用画布&#xff08;canvas&#xff09;标签/元素&#xff0c;另一种不用画布&#xff08;canvas&#xff09;标签/元素主要使用CSS实现。 使用画布&#xff08;canvas&#xff09;标签/元素实现&#xff0c;下面&#xff0c;在画布上…

一键部署自动化运维工具spug

简介 Spug是面向中小型企业设计的轻量级无Agent的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、应用发布部署、在线任务计划、配置中心、监控、报警等一系列功能。 部署 1.创建目录 mkdir -p /opt/spug/{mysql,service,repos} 2.进入目录 cd /o…

Node.js之npm单独与批量升级依赖包的方式

Node.js之npm单独与批量升级依赖包的方式 文章目录 Node.js之npm单独与批量升级依赖包的方式npm查看与升级依赖包1. 单独安装或升级最新版本2. 查看依赖但不升级1. npm outdated2. npm update 3. 批量升级新版本4. npm-check-updates1. 全局安装2. ncu查看可升级的版本3. 升级依…

Leetcode 213 打家劫舍 II

题意理解&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋&#xff0c;每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 &#xff0c;这意味着第一个房屋和最后一个房屋是紧挨着的。同时&#xff0c;相邻的房屋装有相互连通的防盗系统&#xff0c;如果…

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(10)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;9&#xff09; 4.2 PCIe体系结构的组成部件 PCIe总线作为处理器系统的局部总线&#xff0c;其作用与PCI总线类似&#xff0c;主要目的是为了连接处理器系统中的外部设备&…

HiveSQL——用户中两人一定认识的组合数

注&#xff1a;参考文章&#xff1a; SQL之用户中两人一定认识的组合数--HQL面试题36【快手数仓面试题】_sql面试题-快手-CSDN博客文章浏览阅读1.2k次&#xff0c;点赞3次&#xff0c;收藏12次。目录0 需求分析1 数据准备2 数据分析3 小结0 需求分析设表名&#xff1a;table0现…

【从Python基础到深度学习】3. Winscp与Ubuntu使用及配置

一、Ubuntu的使用 1.1 开启与关闭 1.2 修改Ubuntu分辨率 选择适合自己电脑大小的分辨率 1.3 Ubuntu终端 1.4 网络测试 终端中输入&#xff1a; ping www.baidu.com ctr C 退出ping命令 1.5 下载软件 连通安装源 sudo apt update 安装 ssh vim sudo apt install ss…

成为CSDN博客优质创作者或者博客专家吧

成为CSDN博客优质创作者或者博客专家吧 文章目录 成为CSDN博客优质创作者或者博客专家吧一、前言二、如何成为CSDN的博客专家1、2009年的要求和申请方式2、最新的CSDN博客专家要求和申请方式3、创作者身份认证4、CSDN所有认证的介绍 三、写博客的好处1、比较官方的说法&#xf…

Github 2024-02-08 开源项目日报 Top9

根据Github Trendings的统计&#xff0c;今日(2024-02-08统计)共有9个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Ruby项目1HTML项目1Python项目1Scala项目1PLpgSQL项目1Rust项目1NASL项目1C项目1TypeScript项目1非开发语言项目…

【LeetCode】37. 解数独(困难)——代码随想录算法训练营Day30

题目链接&#xff1a;37. 解数独 题目描述 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&…

redis之布隆过滤

目录 1、redis之布隆过滤 2、布隆过滤器原理 3、布隆过滤器使用步骤 初始化bitmap 添加占坑位 判断是否存在圜 1、redis之布隆过滤 布隆过滤&#xff1a;有一个初值都为0的bit数组和多个哈希函数构成&#xff0c;用来快速判断集合中是否存在某个元素。目的&#xff1a;减…