UNIX网络编程——揭开网络编程常见API的面纱【上】
Linux网络编程API函数初步剖析
今天我们来分析一下前几篇博文中提到的网络编程中几个核心的API,探究一下当我们调用每个API时,内核中具体做了哪些准备和初始化工作。

1、socket(family,type,protocol)
当我们在开发网络应用程序时,使用该系统调用来创建一个套接字。该API所做的工作如下所示:
该系统调用主要完成两个任务:“创建套接字”和“为套接字绑定文件句柄”。
socket{}<include/linux/net.h>结构定义如下:
struct socket {
socket_state state; //socket状态
unsigned long flags; //标识,如SOCK_ASYNC_NOSAPCE
const struct proto_ops *ops; //协议特定的socket操作集
struct fasync_struct *fasync_list; //异步唤醒队列
struct file *file; //指向文件的指针
struct sock *sk; //指向下一层中的sock结构
wait_queue_head_t wait; //等待在这个socket上的任务列表
short type; //数据包的类型
};
在创建socket套接字时,就是要完成ops、file和sk等这些成员的初始化。
1). 创建套接字:sock_create()
根据family参数值在全局数组struct net_proto_family net_families[]里找到我们所指定的地址簇。不同类型的地址簇都有一个struct net_proto_family{}类型的对象,例如我们常见的IPv4的inet_family_ops,IPv6的inet6_family_ops,X25协议的ax25_family_ops等。在内核是初始化时,这些模块会在自己的初始化函数内部调用sock_register()接口将各自的地址簇对象注册到net_families[]数组里。
我们分析的焦点集中在IPv4协议簇,即inet_family_ops对象上。重点是inet_create函数,该函数的主要任务就是创建一个socket套接字,并对其中相关结构体成员进行必要的初始化。至于它创建套接字时的依据和原理等到我们讲协议栈时大家就明白了,这里主要是让大家对其流程执行流程有个感性的把握。
sock_alloc()函数中我们创建一个struct socket{}类型的对象,假如叫做A,将socket()系统调用的第二参数type字段赋值给A->type。
在inet_create()函数中,我们根据type的值,在全局数组struct inet_protosw inetsw[]里找到我们对应的协议转换开关。而inetsw[]数组是在inet_init()函数里被初始化的:
其中inetsw_array[]是一个比较重要的数据结构,定义在af_inet.c文件中:
根据type的值,就可以确定struct socket{}->ops,到底是inet_stream_ops、inet_dgram_ops或者inet_sockraw_ops。然后,对应地,就以tcp_prot、udp_prot或raw_prot为输入参数,实例化一个struct sock{}对象sk=sk_alloc()。紧接着建立socket{}和sock{}的关联,最后将socket()系统调用的第三个参数protocol付给sock{}对象中的属性sk_protocol。
看不懂别着急,我说过,这里只是给大家梳理整体流程,等到我们讲了协议栈章节,然后再回头看本篇,就感觉这些东西就太小儿科了。
2). 为套接字绑定文件句柄:sock_map_fd()
我们都知道网络套接字也是一种系统IO,所以不可避免的要与文件系统打交道。每个套接字都对应一个已打开的文件标识符,所以在套接字初始化完成后,就要将其和本地一个唯一的文件标识符关联起来,即建立socket{}和file{}之间的关联关系。
2、bind (sockfd, sockaddr, addrlen)
该系统调用在内核中的执行过程如下:
重点是socket->ops->bind()回调接口。我们现在已经知道了,针对IPv4而言,这里的ops无非就是inet_stream_ops、inet_dgram_ops或inet_sockraw_ops对象。碰巧的是,这三个对象中的bind函数指针均指向inet_bind()函数。只有原始套接字的情况,这里会去调用raw_prot对象的bind回调函数,即raw_bind()。
3、listen(sockfd, backlog)
这里我们可以看到面向无连接的套接字和原始套接字是不用listen的,只有流式套接字才有效。
4、connect(sockfd, sockaddr, addrlen)
从这幅图中我们确实看到,connect()系统调用不但可以面向连接的套接字,也可用于无连接及原始套接字。
5、accept(sockfd, sockaddr, addrlen)
同样地,我们看到只有面向连接的流式套接字调用accept()才有意义。最终调用的是tcp_prot对象的accept成员函数。
本篇主要进一步分析了网络编程中常见的几个API函数内部的调用流程,一方面可以使大家对这些API的有了更深的认识,不是仅仅停留在形而上的层面;另一方面为后面分析协议栈的实现原理,奠定坚实的基础。
未完,待续…
UNIX网络编程——揭开网络编程常见API的面纱【上】的更多相关文章
- UNIX网络编程——揭开网络编程常见API的面纱【下】
Linux网络编程数据收发的API流程分析 只要把数据在协议栈中的流动线路和脉络弄清楚了,关于协议栈的实现部分,理解起来就轻松多了.在网络编程章节的数据接收过程中,我们主要介绍过read ...
- 揭开网络编程常见API的面纱【上】
Linux网络编程API函数初步剖析 今天我们来分析一下前几篇博文中提到的网络编程中几个核心的API,探究一下当我们调用每个API时,内核中具体做了哪些准备和初始化工作. 1.socket(famil ...
- UNIX环境高级编程——TCP/IP网络编程 常用网络信息检索函数
UNIX环境高级编程——TCP/IP网络编程 常用网络信息检索函数 gethostname() getppername() getsockname() gethostbyname() ...
- --系统编程-网络-tcp客户端服务器编程模型、socket、htons、inet_ntop等各API详解、使用telnet测试基本服务器功能
PART1 基础知识 1. 字节序 网络字节序是大端字节序(低地址存放更高位的字节), 所以,对于字节序为小端的机器需要收发网络数据的场景,要对这些数据进行字节序转换. 字节序转换函数,常用的有四个: ...
- Unix环境高级编程(十七)网络IPC套接字
通过网络套接字可以使得不同计算机上运行的进程相互通信. 1.创建套接字 #include <sys/socket.h> Int socket( int domain, int type, ...
- (50)LINUX应用编程和网络编程之五 Linux信号(进程间通信)
信号实现进程间的通信 3.5.1.什么是信号 ...
- (46)LINUX应用编程和网络编程之一Linux应用编程框架
3.1.1.应用编程框架介绍 3.1.1.1.什么是应用编程 (1)整个嵌入式linux核心课程包括5个点,按照学习顺序依次是:裸机.C高级.uboot和系统移植.linux应用编程和网络编程.驱动. ...
- 黑马程序员:Java编程_网络编程
=========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== 网络编程就是两个(或多个)设备(例如计算机)之间的数据传输,更具体的说,网络编程 ...
- (47)LINUX应用编程和网络编程之二Linux文件属性
Linux下的文件系统为树形结构,入口为/ 树形结构下的文件目录: 无论哪个版本的Linux系统,都有这些目录,这些目录应该是标准的.各个Linux发行版本会存在一些小小的差异,但总体来说,还是大体差 ...
随机推荐
- Python 爬取猫眼电影最受期待榜
主要爬取猫眼电影最受期待榜的电影排名.图片链接.名称.主演.上映时间. 思路:1.定义一个获取网页源代码的函数: 2.定义一个解析网页源代码的函数: 3.定义一个将解析的数据保存为本地文件的函数: ...
- [HAOI2011]向量
题目描述 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量 ...
- [AHOI2005]约数研究
题目描述 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机“Samuel II”的长时间运算成为了可能.由于在去年一年的辛苦工作取得了不错的成绩,小联被允许用“Samu ...
- 洛谷P3159 [CQOI2012]交换棋子
巧妙的拆点方式,首先把1看成黑点,0看成空的,几次交换就可以看成一条路径 1)从容量上看,这条路径为1-2-2-2-2-2----2-1 2)从费用上看,这条路径每条边费用都是1 于是用一种巧妙的拆点 ...
- codeforces round #419 B. Karen and Coffee
To stay woke and attentive during classes, Karen needs some coffee! Karen, a coffee aficionado, want ...
- FZU 2158
在密室逃脱游戏中,大家被困在一个密室中,为了逃出密室,需要找到正确的数字密码,于是大家分头行动,分别找到了密码的子序列,而后大家将得到的线索集中整理分析,大家想知道密码最少是多少位. Input 第 ...
- poj 1696 叉积理解
Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3967 Accepted: 2489 Descrip ...
- 【vijos1943】上学路上
题目戳这里 描述 小雪与小可可吵架了,他们决定以后互相再也不理对方了.尤其是,他们希望以后上学的路上不会再相遇. 我们将他们所在城市的道路网视作无限大的正交网格图,每一个整数点 (x,y) 对应了一个 ...
- java版的类似飞秋的局域网在线聊天项目
原文链接:http://www.cnblogs.com/wangleiblog/articles/5323305.html 转载请注明 最近在弄一个java版的局域网在线聊天项目,功能跟飞秋差不多.p ...
- Atom 编辑器安装 linter-eslint 插件,并配置使其支持 vue 文件中的 js 格式校验
安装方式有如下几种. 1.最常用的安装方式. # 进入atom插件文件夹 cd ~/.atom/packages/ # git clone 插件源文件 git clone https://github ...