当前位置: 首页 > news >正文

深入理解Linux网络(三):TCP对象创建

深入理解Linux网络(三):TCP对象创建

  • TCP对象创建
    • inet_create
    • sock_init_data

TCP对象创建

常见的三句TCP编程:

int main()
{int sk = socket(AF_INET, SOCK_STREAM, 0);connect(sk, ...)recv(sk, ...)
}

简单的两三⾏代码,但实际上⽤户进程和内核配合做了⾮常多的⼯作。
首先⽤户进程发起创建 socket 的指令,然后切换到内核态完成了内核对象的初始化。
接着在数据包的接收上,是硬中断和 ksoftirqd 进程在进⾏处理。
当 ksoftirqd 进程处理完以后,再通知到相关的⽤户进程。
从创建 socket,到⽹络包抵达⽹卡到被接收,流程如下:
在这里插入图片描述
数据结构间的调用如下:
在这里插入图片描述

//file:net/socket.c
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{......retval = sock_create(family, type, protocol, &sock);
}

sock_create 继续调用 __sock_create:

//file:net/socket.c
int __sock_create(struct net *net, int family, int type, int protocol,struct socket **res, int kern)
{struct socket *sock;const struct net_proto_family *pf;......//分配 socket 对象sock = sock_alloc();//获得每个协议族的操作表pf = rcu_dereference(net_families[family]);//调⽤每个协议族的创建函数, 对于 AF_INET 对应的是err = pf->create(net, sock, protocol, kern);
}

net_proto_family->create 会调用 inet_create:

//file:net/ipv4/af_inet.c
static int inet_create(struct net *net, struct socket *sock, int protocol, int kern)
{struct sock *sk;//查找对应的协议,对于TCP SOCK_STREAM 就是获取到了//static struct inet_protosw inetsw_array[] =//{// {// .type = SOCK_STREAM,// .protocol = IPPROTO_TCP,// .prot = &tcp_prot,// .ops = &inet_stream_ops,// .no_check = 0,// .flags = INET_PROTOSW_PERMANENT |// INET_PROTOSW_ICSK,// },//}list_for_each_entry_rcu(answer, &inetsw[sock->type], list){//将 inet_stream_ops 赋到 socket->ops 上sock->ops = answer->ops;//获得 tcp_protanswer_prot = answer->prot;//(1)分配 sock 对象, 并把 tcp_prot 赋到 sock->sk_prot 上sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);//(2)对 sock 对象进⾏初始化sock_init_data(sock, sk);}
}

针对上面的代码:

inet_create

inet_create 中根据类型 SOCK_STREAM 查找到对于 tcp 定义的操作⽅法实现集合 inet_stream_ops 和 tcp_prot。并把它们分别设置到 socket->ops 和 sock->sk_prot 上。
在这里插入图片描述

sock_init_data

sock_init_data 中将 sock 中的 sk_data_ready 函数指针进⾏了初始化,设置为默认 sock_def_readable()。
在这里插入图片描述

//file: net/core/sock.c
void sock_init_data(struct socket *sock, struct sock *sk)
{sk->sk_data_ready = sock_def_readable;sk->sk_write_space = sock_def_write_space;sk->sk_error_report = sock_def_error_report;
}

当软中断上收到数据包时会通过调⽤ sk_data_ready 函数指针(实际被设置成了 sock_def_readable()) 来唤醒在 sock 上等待的进程。
⾄此,⼀个 tcp对象( AF_INET 协议族下 SOCK_STREAM对象)就算是创建完成了。
这⾥花费了⼀次 socket 系统调⽤的开销。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [HTML]一文掌握
  • MySQL中EXPLAIN关键字详解
  • Python入门基础教程(非常详细)
  • C++ | Leetcode C++题解之第264题丑数II
  • 轨道相互作用和带隙
  • 为什么要从C语言开始编程
  • Python 热门面试题(七)
  • 十五、公开课
  • 基于SSM的网上选课系统
  • 【ACM独立出版|EI检索稳定】2024年智能感知与模式识别国际学术会议(ISPC 2024,9月6日-8)
  • Blender中的重拓扑修改器如何使用?
  • Windows系统笔记本无法连接Wi-Fi常见原因及解决办法
  • 【Android】使用视图绑定ViewBinding来代替findViewById
  • pdf提取其中一页怎么操作?提取PDF其中一页的方法
  • 02-用户画像-技术架构+业务划分
  • [译]Python中的类属性与实例属性的区别
  • 【347天】每日项目总结系列085(2018.01.18)
  • DOM的那些事
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Javascript基础之Array数组API
  • mysql 5.6 原生Online DDL解析
  • mysql innodb 索引使用指南
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 创建一种深思熟虑的文化
  • 讲清楚之javascript作用域
  • 聊聊flink的BlobWriter
  • 嵌入式文件系统
  • 区块链分支循环
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 深入浏览器事件循环的本质
  • 算法之不定期更新(一)(2018-04-12)
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 线上 python http server profile 实践
  • 从如何停掉 Promise 链说起
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #Linux(权限管理)
  • #宝哥教你#查看jquery绑定的事件函数
  • (1)(1.13) SiK无线电高级配置(五)
  • (1)Android开发优化---------UI优化
  • (1)虚拟机的安装与使用,linux系统安装
  • (30)数组元素和与数字和的绝对差
  • (三分钟)速览传统边缘检测算子
  • (文章复现)基于主从博弈的售电商多元零售套餐设计与多级市场购电策略
  • (轉)JSON.stringify 语法实例讲解
  • .net core Redis 使用有序集合实现延迟队列
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .NET单元测试使用AutoFixture按需填充的方法总结
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .NET建议使用的大小写命名原则
  • .NET上SQLite的连接