5、accept(sockfd, sockaddr, addrlen)

文章插图
同样地,我们看到只有面向连接的流式套接字调用accept()才有意义 。最终调用的是tcp_prot对象的accept成员函数 。
需要C/C++ Linux高级服务器架构师学习资料后台私信“资料”(包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等)

文章插图
Linux网络编程数据收发的API流程分析
只要把数据在协议栈中的流动线路和脉络弄清楚了,关于协议栈的实现部分,理解起来就轻松多了 。在网络编程章节的数据接收过程中,我们主要介绍过read()、recv()、recvfrom()还有一个recvmsg()没介绍到,今天我们就来看一下这几个API函数到底有什么差别 。
数据接收
在接收数据的过程,主要分两个阶段:BOTTOM-HALF和TOP-HALF 。 BOTTOM-HALF:

文章插图
当从网卡驱动收到数据包后即进入BOTTOM-HALF阶段,在这里要根据以太帧头部中的类型字段来确定上层承载的具体协议类型,如IP,或ARP、RARP等 。IP报文的处理函数通常交付给ip_recv()函数来处理,然后数据进入网络层,具体流程: 如果该数据包是发给本机的一般调用ip_local_deliver()函数,如果是需要本机转发给出去的,并且本机也开启了转发功能,那么就会调用ip_forward()函数 。在这里我们看到了Netfilter的身影,好久没看到它了,还是有些亲切 。大家可以结合这幅图回头再理解一下Netfilter和协议栈的关系 。BOTTOM-HALF最后将收到的skb填充到socket套接字的接收队列里,参见下图 。
TOP-HALF:
紧承BOTTOM-HALF阶段,该阶段的主要任务就是从接收队列里拿出一个skb然后将其传递到用户空间去,如下:

文章插图
可以看出,这几个函数的内部最终都统一到了一起:__sock_recvmsg() 。
数据发送
同样的,数据发送也分两个阶段,对照接收的情况,发送数据时肯定也存在一个发送队列,这样想就对了 。前面关于发送数据包时我们介绍过的API有write()、send()、sendto()还有一个sendmsg()没介绍到 。 TOP-HALF如下:

文章插图
BOTTOM-HALF如下所示:

文章插图
经过这么一份探索,我们对这几个数据收发的API至少理解的要比别人深刻些了吧 。
推荐阅读
- 中考英语作文十大常见错误分析
- 2 种从 Linux 终端下载文件的方法
- 在 Ubuntu 和其他 Linux 发行版上使用 Yarn
- Linux 软链接和硬链接
- 常见感冒药的主要成分是什么呢?
- Linux下diff的操作详解
- 黄芪的食用量是多少
- 黄芪和炙黄芪的区别有哪些
- 原发性癫痫
- 周围神经病是什么
