本节我们主要介绍一下nginx中的分散发送实现。
1. os/unix/ngx_writev_chain.c源代码
在介绍函数的具体实现之前,我们这里再次给出ngx_chain_t
数据结构示意图:
1.1 函数ngx_writev_chain()
下面我们来简单分析一下这个函数:
1) 处理!wev->ready
情况
wev->ready
为0时,表示当前socket尚未准备好发送数据,一般情况是当前发送缓冲区已满。
2) 对kqueue情形下pending_eof的处理
我们当前不支持NGX_HAVE_KQUEUE。在kqueue模型下,wev->pending_eof表示当前socket 连接已经关闭,但是当前还未被处理。
3) 设置一次发送的最大发送数量
在ngx_auto_config.h头文件中,我们有如下定义:
#ifndef NGX_MAX_SIZE_T_VALUE
#define NGX_MAX_SIZE_T_VALUE 2147483647
#endif
因为这里size_t表示数据的最大值为NGX_MAX_SIZE_T_VALUE
,另外可能还需要留有一些其他的空间,因此这里限定一次发送数据的最大大小为:
limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
这里ngx_pagesize
大小为4096.
4) 发送数据
1.2 函数ngx_output_chain_to_iovec()
下面简单分析一下合并流程:
1.3 函数ngx_writev()
这里调用writev()函数将数据通过socket发送出去。这里主要是对发送出错情况下,的处理:
-
NGX_EAGAIN: 表示当前socket并未准备好发送数据,一般是在发送缓冲区已经满的情况下出现
-
NGX_EINTR: 此种情况是受中断影响,直接继续尝试发送即可
-
default: socket连接出现问题,报错退出