当前位置: 首页 > 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 系统调⽤的开销。

http://www.lryc.cn/news/403988.html

相关文章:

  • windows server——4.安装DNS管理器
  • 速盾:金融行业服务器如何避免DDoS攻击?
  • 谷粒商城实战笔记-38-前端基础-Vue-指令-单向绑定双向绑定
  • MyPostMan 迭代文档管理、自动化接口闭环测试工具(自动化测试篇)
  • https和http有哪些区别?
  • Bubbliiiing 的 Retinaface rknn python推理分析
  • Web前端-Web开发HTML基础8-nav
  • 如何建设和维护数据仓库:深入指南
  • 海思arm-hisiv400-linux-gcc 交叉编译rsyslog 记录心得
  • IDEA工具中Java语言写小工具遇到的问题
  • 2-38 基于matlab的蚁群算法优化无人机uav巡检
  • 解决selenium打印保存为PDF时图片未加载成功的问题
  • 如何将PDF转换成可以直接编辑的CAD图纸?
  • 【STM32】理解时钟树(图示分析)
  • 动态内存四个函数
  • DevExpress WPF中文教程 - 为项目添加GridControl并将其绑定到数据
  • 高性能分布式IO系统BL205 OPC UA耦合器
  • live555 rtsp服务器实战之doGetNextFrame
  • Nginx系列-3 servername优先级和location优先级和常用正则表达式
  • python—爬虫爬取电影页面实例
  • 实现图片拖拽和缩小放大功能。
  • 昇思25天学习打卡营第18天|munger85
  • nginx配置文件说明
  • 用不同的url头利用Python访问一个网站,把返回的东西保存为txt文件
  • 一文掌握Prometheus实现页面登录认证并集成grafana
  • 欢迎来到 Mint Expedition:Web3 和 NFT 的新时代开始
  • 针对环境构图的全局一致性扫描点云数据对齐(Graph SLAM)
  • Matlab学习笔记01 - 基本数据类型
  • 基于重要抽样的主动学习不平衡分类方法ALIS
  • Python爬虫(基本流程)