linux socket bind 内核详解,Socket与系统调用深度分析(示例代码)

2023-11-08

1、 什么是系统调用

操作系统通过系统调用为运行于其上的进程提供服务。当用户态进程发起一个系统调用, CPU 将切换到 内核态 并开始执行一个 内核函数 。 内核函数负责响应应用程序的要求,例如操作文件、进行网络通讯或者申请内存资源等。在Linux中系统调用是有Linux内核提供的各种功能服务,为了便于调用Linux提供了一个底层C语言库libc(glibc是GUN版本的libc,其他类似库还有uclibc、klibc),目前glibc是linux标准函数库,这些都对系统系统接口打包成了标准C函数,这些函数一般就成为系统调用。系统调用可以通过syscall()函数发起,或者调用每个对应的一个C函数,这些函数定义在 或者 头文件中。Linux系统中通过软中断0x80调用实现控制权转移给内核,内容执行完成后返回结果。所有系统调用在linux内核的源文件目录" arch/x86/kernel"中的各种文件中定义。

内核实现了很多的系统调用函数, 这些函数会有自己的名字, 以及编号. 用户要调用系统调用, 首先需要使用  int 0x80 触发软中断. 这个指令会在0x80代表十进制的128, 所以这个指令会找终端向量表的128项, 找到以后, 跳转到相应的函数, 这个处理函数就是system_call. 这个中断向量表的设置, 是在操作系统初始化的时候, 通过trap_init()函数设置的. 在进入中断处理函数system_call以后, 首先要进行一般的中断处理流程, 即保护现场. 这个体现在指令SAVE_ALL(494行)上. 然后有一个重要的函数调用 call *sys_call_table(,%eax,4). 这个表示查找系统调用函数表(), 然后调用相应的系统调用函数. 对于32位的系统, 函数位置存了4个Bytes, eax中是我们传入的系统调用号, 所以4*eax,就可以找到对应的系统调用函数, 执行函数. 之后还需要进行返回值的保存等工作.

2、 socket相关系统调用的内核处理函数深入分析

1)        因为上一次实验是在shiyanlou环境下完成,所以此次实验需要重新下载下载linux-5.0.1的内核并编译内核,并制作根文件系统。

20191219155311140619.png

20191219155311540008.png

2)

解Linux内核中socket接口层的代码,找出112号系统调用socketcall的内核处理函数sys_socketcall,理解socket接口函数编号和对应的socket接口内核处理函数 通过前面构建MenuOS实验环境使得我们有方法跟踪socket接口通过系统调用进入内核代码,在我们的环境中socket接口通过112号系统调用socketcall进入内核的

System call vectors.

Argument checking cleaned up. Saved 20% in size.

This function doesn‘t need to set the kernel lock because

it is set by the callees.

2490 */

2491

2492SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)

2493{

...

2517 switch (call) {

2518 case SYS_SOCKET:

2519       err = sys_socket(a0, a1, a[2]);

2520       break;

2521 case SYS_BIND:

2522       err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]);

2523       break;

2524 case SYS_CONNECT:

2525       err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]);

2526       break;

2527 case SYS_LISTEN:

2528       err = sys_listen(a0, a1);

2529       break;

2530 case SYS_ACCEPT:

2531       err = sys_accept4(a0, (struct sockaddr __user *)a1,

2532                       (int __user *)a[2], 0);

2533       break;

2534 case SYS_GETSOCKNAME:

2535       err =

2536           sys_getsockname(a0, (struct sockaddr __user *)a1,

2537                         (int __user *)a[2]);

2538       break;

2539 case SYS_GETPEERNAME:

2540       err =

2541           sys_getpeername(a0, (struct sockaddr __user *)a1,

2542                         (int __user *)a[2]);

2543       break;

2544 case SYS_SOCKETPAIR:

2545       err = sys_socketpair(a0, a1, a[2], (int __user *)a[3]);

2546       break;

2547 case SYS_SEND:

2548       err = sys_send(a0, (void __user *)a1, a[2], a[3]);

2549       break;

2550 case SYS_SENDTO:

2551       err = sys_sendto(a0, (void __user *)a1, a[2], a[3],

2552                     (struct sockaddr __user *)a[4], a[5]);

2553       break;

2554 case SYS_RECV:

2555       err = sys_recv(a0, (void __user *)a1, a[2], a[3]);

2556       break;

2557 case SYS_RECVFROM:

2558       err = sys_recvfrom(a0, (void __user *)a1, a[2], a[3],

2559                        (struct sockaddr __user *)a[4],

2560                        (int __user *)a[5]);

2561       break;

2562 case SYS_SHUTDOWN:

2563       err = sys_shutdown(a0, a1);

2564       break;

2565 case SYS_SETSOCKOPT:

2566       err = sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]);

2567       break;

2568 case SYS_GETSOCKOPT:

2569       err =

2570           sys_getsockopt(a0, a1, a[2], (char __user *)a[3],

2571                        (int __user *)a[4]);

2572       break;

2573 case SYS_SENDMSG:

2574       err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);

2575       break;

2576 case SYS_SENDMMSG:

2577       err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);

2578       break;

2579 case SYS_RECVMSG:

2580       err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);

2581       break;

2582 case SYS_RECVMMSG:

2583       err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],

2584                        (struct timespec __user *)a[4]);

2585       break;

2586 case SYS_ACCEPT4:

2587       err = sys_accept4(a0, (struct sockaddr __user *)a1,

2588                       (int __user *)a[2], a[3]);

2589       break;

2590 default:

2591       err = -EINVAL;

2592       break;

2593 }

2594 return err;

2595}

2596

在我们的实验环境中,socket接口的调用是通过给socket接口函数编号的方式通过112号系统调用来处理的。这些socket接口函数编号的宏定义见/linux-3.18.6/include/uapi/linux/net.h#26

26#define SYS_SOCKET 1            /* sys_socket(2)           */

27#define SYS_BIND     2            /* sys_bind(2)              */

28#define SYS_CONNECT    3            /* sys_connect(2)         */

29#define SYS_LISTEN  4            /* sys_listen(2)             */

30#define SYS_ACCEPT 5            /* sys_accept(2)           */

31#define SYS_GETSOCKNAME  6            /* sys_getsockname(2)        */

32#define SYS_GETPEERNAME   7            /* sys_getpeername(2)        */

33#define SYS_SOCKETPAIR 8            /* sys_socketpair(2)             */

34#define SYS_SEND    9            /* sys_send(2)              */

35#define SYS_RECV    10          /* sys_recv(2)               */

36#define SYS_SENDTO      11          /* sys_sendto(2)           */

37#define SYS_RECVFROM  12          /* sys_recvfrom(2)        */

38#define SYS_SHUTDOWN 13          /* sys_shutdown(2)             */

39#define SYS_SETSOCKOPT      14          /* sys_setsockopt(2)            */

40#define SYS_GETSOCKOPT     15          /* sys_getsockopt(2)           */

41#define SYS_SENDMSG    16          /* sys_sendmsg(2)        */

42#define SYS_RECVMSG    17          /* sys_recvmsg(2)         */

43#define SYS_ACCEPT4     18          /* sys_accept4(2)         */

44#define SYS_RECVMMSG 19          /* sys_recvmmsg(2)             */

45#define SYS_SENDMMSG 20          /* sys_sendmmsg(2)            */

接下来我们根据TCP server程序调用socket接口的顺序依次看一下socket、bind、listen、accept等socket接口的内核处理函数。

socket接口函数的内核处理函数sys_socket

1377SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)

1378{

1379 int retval;

1380 struct socket *sock;

...

1397 retval = sock_create(family, type, protocol, &sock);

...

socket接口函数主要作用是建立socket套接字描述符,Unix-like系统非常成功的设计是将一切都抽象为文件,socket套接字也是一种特殊的文件,sock_create内部就是使用文件系统中的数据结构inode为socket套接字分配了文件描述符。socket套接字与普通的文件在内部存储结构上是一致的,甚至文件描述符和套接字描述符是通用的,但是套接字和文件还是特殊之处,因此定义了结构体struct socket,struct socket的结构体定义见/linux-3.18.6/include/linux/net.h#105,具体代码摘录如下:

95/**

96 *  struct socket - general BSD socket

97 *  @state: socket state (%SS_CONNECTED, etc)

98 *  @type: socket type (%SOCK_STREAM, etc)

99 *  @flags: socket flags (%SOCK_ASYNC_NOSPACE, etc)

100 *  @ops: protocol specific socket operations

101 *  @file: File back pointer for gc

102 *  @sk: internal networking protocol agnostic socket representation

103 *  @wq: wait queue for several uses

104 */

105struct socket {

106  socket_state         state;

107

108  kmemcheck_bitfield_begin(type);

109  short                    type;

110  kmemcheck_bitfield_end(type);

111

112  unsigned long             flags;

113

114  struct socket_wq __rcu *wq;

115

116  struct file       *file;

117  struct sock            *sk;

118  const struct proto_ops *ops;

119};

sock_create内部还根据指定的网络协议族family和protocol初始化了相关协议的处理接口到结构体struct socket中,结构体struct socket在后续的分析和理解中还会用到,这里简单略过用到时再具体研究。

bind接口函数的内核处理函数sys_bind

1519/*

1520 *     Bind a name to a socket. Nothing much to do here since it‘s

1521 *     the protocol‘s responsibility to handle the local address.

1522 *

1523 *     We move the socket address to kernel space before we call

1524 *     the protocol layer (having also checked the address is ok).

1525 */

1526

1527SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)

1528{

1529 struct socket *sock;

1530 struct sockaddr_storage address;

1531 int err, fput_needed;

1532

1533 sock = sockfd_lookup_light(fd, &err, &fput_needed);

1534 if (sock) {

1535       err = move_addr_to_kernel(umyaddr, addrlen, &address);

1536       if (err >= 0) {

1537              err = security_socket_bind(sock,

1538                                      (struct sockaddr *)&address,

1539                                      addrlen);

1540              if (!err)

1541                     err = sock->ops->bind(sock,

1542                                         (struct sockaddr *)

1543                                         &address, addrlen);

1544       }

1545       fput_light(sock->file, fput_needed);

1546 }

1547 return err;

1548}

如上代码可以看到,move_addr_to_kernel将用户态的struct sockaddr结构体数据拷贝到内核里的结构体变量struct sockaddr_storage address,然后使用sock->ops->bind将该网络地址绑定到之前创建的套接字。这里用到了通过套接字描述符fd找到之前分配的套接字struct socket *sock,利用该套接字中的成员const struct proto_ops *ops找到对应网络协议的bind函数指针即sock->ops->bind。这里即是一个socket接口层通往具体协议处理的接口。

listen接口函数的内核处理函数sys_listen

1550/*

1551 *     Perform a listen. Basically, we allow the protocol to do anything

1552 *     necessary for a listen, and if that works, we mark the socket as

1553 *     ready for listening.

1554 */

1555

1556SYSCALL_DEFINE2(listen, int, fd, int, backlog)

1557{

1558 struct socket *sock;

1559 int err, fput_needed;

1560 int somaxconn;

1561

1562 sock = sockfd_lookup_light(fd, &err, &fput_needed);

1563 if (sock) {

1564       somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;

1565       if ((unsigned int)backlog > somaxconn)

1566              backlog = somaxconn;

1567

1568       err = security_socket_listen(sock, backlog);

1569       if (!err)

1570              err = sock->ops->listen(sock, backlog);

1571

1572       fput_light(sock->file, fput_needed);

1573 }

1574 return err;

1575}

listen接口的主要作用是通知网络底层开始监听套接字并接收网络连接请求,listen接口正常处理完TCP服务就已经启动了,只是这时网络连接请求都会暂存在缓冲区,等调用accept建立连接,listen接口函数的参数backlog就是用来配置支持的连接数。

我们发现实际处理的工作是由sock->ops->listen完成的,这也是一个socket接口层通往具体协议处理的接口。

accept接口函数的内核处理函数sys_accept

内核处理函数sys_accept的主要功能是调用sys_accept4完成的,sys_accept4见/linux-3.18.6/net/socket.c#1589,具体代码摘录如下:

1577/*

1578 *     For accept, we attempt to create a new socket, set up the link

1579 *     with the client, wake up the client, then return the new

1580 *     connected fd. We collect the address of the connector in kernel

1581 *     space and move it to user at the very end. This is unclean because

1582 *     we open the socket then return an error.

...

1589SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,

1590       int __user *, upeer_addrlen, int, flags)

1591{

...

1608 newsock = sock_alloc();

...

1612 newsock->type = sock->type;

1613 newsock->ops = sock->ops;

...

1621 newfd = get_unused_fd_flags(flags);

...

1627 newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);

...

1639 err = sock->ops->accept(sock, newsock, sock->file->f_flags);

...

1643 if (upeer_sockaddr) {

1644       if (newsock->ops->getname(newsock, (struct sockaddr *)&address,

...

1649       err = move_addr_to_user(&address,

...

1657 fd_install(newfd, newfile);

1658 err = newfd;

...

1668}

在TCP的服务器端通过socket函数创建的套接字描述符只是用来监听客户连接请求,accept函数内部会为每一个请求连接的客户创建一个新的套接字描述符专门负责与该客户端进行网络通信,并将该客户的网络地址和端口等地址信息返回到用户态。这里涉及更多的网络协议处理的接口如sock->ops->accept、ewsock->ops->getname。

send和recv接口的内核处理函数类似也是通过调用网络协议处理的接口来将具体的工作交给协议层来完成,比如sys_recv最终调用了sock->ops->recvmsg,sys_send最终调用了sock->ops->sendmsg,但send和recv接口涉及网络数据流,是理解网络部分的关键内容

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux socket bind 内核详解,Socket与系统调用深度分析(示例代码) 的相关文章

  • 面试官mysql的索引了解多少,这一次我不会再被问懵了

    mysql数据库我相信基本大部分公司会选择mysql数据库 作为存储引擎 MySQL 数据库管理系统具有以下系统特性 使用 C 和 C 编写 并使用多种编译器进行测试 保证源代码的可移植性 支持 AIX FreeBSD HP UX Linu
  • 服务器物理机使用ESXI虚拟化并划分虚拟机

    前言 最近因为增加了一台物理机 所以需要对物理机进行虚拟化后划分虚拟机 下面主要来介绍物理机划分虚拟机的操作步骤 物理机虚拟化 1 下载VMware VMvisor Installer 6 0 0 update01 3029758 x86
  • 零基础如何学习Web 安全,如何让普通人快速入门网络安全?

    前言 网络安全现在是朝阳行业 缺口是很大 不过网络安全行业就是需要技术很多的人达不到企业要求才导致人才缺口大 帮助安全学习 免费领取网络安全面试题 学习路线 视频教程 工具 需要可以微信扫描下方CSDN官方认证二维码免费领取 保证100 免
  • C语言之if语句

    C语言之if语句 一 简单形式的if语句可以让程序选择执行一条语句 或者跳过这条语句 实例1 下面我们通过一个简单的代码来判定学生成绩是否合格 include
  • 如何打开iso文件

    iso文件用什么打开 iso文件用什么打开 使用光驱可以打开iso文件 iso文件是一种光盘 CD 上的系统文件格式 因此我们只需要将iso文件写入到光盘当中 然后用光驱打开光盘即可安装iso文件软件了 目前我们常购买的光盘系统盘就是商家将
  • 服务器远程如何修改密码,服务器远程如何修改密码

    服务器远程如何修改密码 内容精选 换一换 本地Windows操作系统主机 推荐使用 方法1 使用RDP文件登录在控制台单击 远程登录 下载RDP文件至本地 运行RDP文件 输入密码 密钥鉴权方式请先获取登录密码 登录远程桌面 详细操作请参考
  • 如何屏蔽百度搜索推广

    这几天大家都在说百度推广的事 笔者没什么好说的 毕竟已经很久没有见过百度推广了 不过说实话 很多时候谷歌搜出来的东西才是我想要的 今天就讲一下如何使用插件屏蔽百度推广 一 工具 1 chrome浏览器 2 Tampermonkey 插件 c
  • 性能优化工具:SQL Profiler

    https www cnblogs com kissdodog p 3398523 html 一 SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程 其作用如下 图形化监视SQL Server查询 在
  • Hexo + GitHub 搭建个人博客(二) Hexo monie主题

    前言 hexo theme monie 卡片化设计 安装 Git 安装 在项目的根目录下执行 git clone https gitee com lyboy6 hexo themes monie git themes monie npm 安
  • STM32NVIC中断优先级管理

    目录 抢占优先级响应优先级区别 中断设置相关寄存器 IO unit8 t IP 240 中断优先级控制寄存器组 中断参数初始化函数NVIC Init NVIC InitTypeDef结构体 抢占优先级响应优先级区别 抢占优先级高的可以打断正
  • 常用的LaTeX公式用法

    常用的LaTeX公式用法 常用的latex公式用法 常用的latex公式用法 加法 效果 减法 效果 乘法 叉乘 times 例子 a b a times b a b 效果 a b 乘法 点乘 cdot
  • 本地Linux服务器安装宝塔面板,并内网穿透实现公网远程登录

    文章目录 前言 1 安装宝塔 2 安装cpolar内网穿透 3 远程访问宝塔 4 固定http地址 5 配置二级子域名 6 测试访问二级子域名 转发自CSDN远程穿透的文章 Linux安装宝塔 并实现公网远程登录宝塔面板 内网穿透 前言 宝
  • MySQL数据库基本操作-DQL

    文章目录 一 基本查询 二 运算符 2 1 算术运算符 2 2 位运算符和逻辑运算符 2 3 比较运算符 三 排序查询 四 聚合查询 4 1 聚合查询举例 4 2 NULL值处理 五 分组查询 六 分页查询 七 INSERT INTO SE
  • ONES CTO

    2021年4月24日 4月26日 华为开发者大会在深圳大学城举办 本次大会主题为 每一个开发者都了不起 来自华为及各行业的技术大咖们与开发者汇聚一堂 探讨最新 ICT 技术在行业的深度创新与最佳实践 ONES CTO 冯斌先生受邀出席大会
  • 打开页面js自动加载的方法

    一 js方法 1 在body标签加onload属性 例 2 window onload方法 例 二 jQuery方法 1 window onload function alert 自动加载 2 document ready function
  • 全国计算机等级考试题库二级C操作题100套(第95套)

    第95套 给定程序中 函数fun的功能是 计算N N矩阵的主对角线元素和反向对角线元素之和 并作为函数值返回 注意 要求先累加主对角线元素中的值 然后累加反向对角线元素中的值 例如 若N 3 有下列矩阵 1 2 3 4 5 6 7 8 9
  • C++常量

    C 常量 常量是固定值 在程序执行期间不会改变 这些固定的值 又叫做字面量 常量可以是任何的基本数据类型 可分为整型数字 浮点数字 字符 字符串和布尔值 常量就像是常规的变量 只不过常量的值在定义后不能进行修改 整数常量 整数常量可以是十进
  • android webview 加载https

    在设置的WebViewClient 接收所有信任证书 wv setWebViewClient new WebViewClient Override public void onReceivedSslError WebView view Ss
  • 利用mysqldump实现分库分表备份的shell脚本

    一 信息摘要 linux版本 CentOS 7 9 mysql版本 MySQL 5 7 36 脚本实现功能 利用mysqldump工具实现对mysql中的数据库分库备份 和对所备份数据库中的表分表备份 二 shell脚本 bin bash

随机推荐

  • tensorflow的gpu版本错误

    出现错误 E tensorflow stream executor cuda cuda event cc 48 Error polling for event status failed to query event CUDA ERROR
  • statsmodels笔记:绘制ACF和PACF

    理论部分见 算法笔记 ARIMA UQI LIUWJ的博客 CSDN博客 3 1 3 2 1 绘制自相关函数ACF from statsmodels graphics tsaplots import plot acf plot acf df
  • Pytroch 模型权重初始化

    目录 1 概念 2 权值初始化方法 2 1 常数初始化 2 2 均匀分布初始化 2 3 正态分布初始化 2 4 Xavier 均匀分布 2 5 Xavier 正态分布 2 6 kaiming 均匀分布 2 7 kaiming 正态分布 2
  • 在产品中,我们常说的A端/B端/C端是什么?

    一 引言 在IT产品中 我们常常把各类型的技术系统分为A端 B端 C端 那它们到底是什么呢 又是有什么区别呢 今天小郭就带大家来仔细看看 二 我们常说的A端 B端 C端 R端是什么 2 1 产品分类 IT产品大致可以分为这四个类型 A端 是
  • 大数据数据仓库建设流程概述

    数据仓库的逻辑分层架构 想看懂数据仓库的逻辑分层架构 必须先弄懂以下4大概念 数据源 数据来源 互联网公司的数据来源随着公司的规模扩张而呈递增趋势 同时自不同的业务源 比如埋点采集 客户上报 API等 ODS层 数据仓库源头系统的数据表通常
  • html加载页面转圈圈怎么打,js实现等待加载“转圈圈”效果

    完美实现加载转圈圈效果 js代码 function showLoading show if show document getElementById over style display block document getElementB
  • MA35D1测试-记录

    1 查看拨码开关的启动设定 找到开发板 拨码快关 复位按键 电源开关的位置 2 三根线和软件 一根5V 2A电源适配线 两根usb线 三根线 一根5V 2A电源适配线 两根usb线 电源线插上 确保可以波动开关 有灯 点亮 usb线 在有电
  • 关键词提取(keyword extraction)技术

    目录 1 统计方法 Statistical Method 1 1 TF 1 2 TFIDF 1 3 YAKE 2 图方法 Graph Based Approaches 2 1 PageRank 2 2 TextRank 2 2 Single
  • easy-excel复杂格式

    1 支持easy excel模板与不同列表循环打印 合并表头 背景色 2 支持excel的高度自适应 3 支持多sheet页面模板打印 代码如下 Test public void compositeFill1 模板注意 用 来表示你要用的变
  • Docker 容器基础介绍

    目录 一 基础介绍 二 Docker 安装 linux 安装 vim linux 安装 sudo 三 Docker 常用操作命令 1 Docker windows版本安装 2 设置Docker镜像加速器 3 Docker 其它镜像相关 以D
  • 基因序列相似度(LCS)

    目录 1 问题描述 2 一些细节 3 思路 4 代码 1 问题描述 基因序列包含四种核苷酸 分别用A C T和G四个字母简单地表示 编写一个程序 按以下规则比较两个基因并确定它们的相似程度 规则 使用对齐方法 可以在基因的适当位置插进空格
  • [人工智能-深度学习-20]:卷积神经网络CNN - 全连接网络的缺点与CNN的使命

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 120732872 目录 第1章 全连接
  • Jlink使用技巧之RTT和J-Scope

    在调试单片机程序时 串口打印是一种非常常用的方式 有时候 硬件上没有预留串口时 就需要采用其它方式进行打印调试 1 Jlink SEGGER RTT Jlink SEGGER RTT是一种非常好用的方式 只需要通过Jlink的SWD或者JT
  • 前端面试题之CSS

    文章目录 遗留问题 1 css盒子模型 2 css选择器 3 伪类与伪元素的区别 回答 4 css中有哪些属性可以继承 5 CSS优先级 6 居中一个div 7 块级元素和行内元素的区别 8 position的值 9 CSS3 有哪些新特性
  • logminer介绍

    理解和使用Oracle 8i分析工具LogMiner Oracle LogMiner 是Oracle公司从产品8i以后提供的一个实际非常有用的分析工具 使用该工具可以轻松获得Oracle 重作日志文件 归档日志文件 中的具体内容 特别是 该
  • Windows下查看Android手机APP日志

    1 JDK环境搭建 略 在命令行窗口输入 java version 回车后显示版本号则表示JDK环境安装成功 2 配置adb环境 点击下方打开官网链 下载适用于Windows的SDK Platform Tools 下载成功后解压该文件 ht
  • 定时任务动态管理-Scheduled

    文章目录 前言 一 架构流程图 二 代码实现流程 1 引入库 2 代码流程 前言 定时任务动态管理分为两种方式 方式一 Web前台配置Trigger触发器 关联Cron ThreadPoolTaskScheduler类创建Scheduler
  • 蓝桥杯每日一题2023.9.21

    蓝桥杯2021年第十二届省赛真题 异或数列 C语言网 dotcpp com 题目描述 Alice 和 Bob 正在玩一个异或数列的游戏 初始时 Alice 和 Bob 分别有一个整数 a 和 b 有一个给定的长度为 n 的公共数列 X1 X
  • 与ajax类似的技术,介绍Ajax与jQuery技术

    Ajxs技术 异步的JavaScript与XML 已有多种技术的组合 Ajax的优点是什么 1 可以实现客户端的异步请求操作2 进而在不需要刷新页面的情况下与服务器进行通信 减少用户的等待时间3 减轻服务器和带宽的负担 提供更好的服务响应
  • linux socket bind 内核详解,Socket与系统调用深度分析(示例代码)

    1 什么是系统调用 操作系统通过系统调用为运行于其上的进程提供服务 当用户态进程发起一个系统调用 CPU 将切换到 内核态 并开始执行一个 内核函数 内核函数负责响应应用程序的要求 例如操作文件 进行网络通讯或者申请内存资源等 在Linux