您的位置:首页 > 其它

fastcgi协议分析与实例

2016-11-07 23:51 232 查看


1.序言

最近在用c++实现一个简易web服务器。在实现之前大体理了一下一个web服务器主要咋样实现。当时单纯的认为只需要将浏览器发来的http请求解析,找到对应的文件,然后给浏览器一个响应,把其要获取的文件发给它就完事。可是写了没几天就遇到了瓶颈。因为我们的浏览器并不能解析动态的PHP文件,那么如果获取的http请求的请求文件为.php文件我们该杂么办呢?


2.将.php转换为.html的php-fpm

我们都知道php是一门解释型语言,当php在执行时,php内核都会为我们调用php解释器来帮我们解释程序。而我们的php-fpm相比php内核也具有此功能(事实上,php最新版本以把php-fpm当做一个补丁打在php内核之中了) 

php-fpm的安装方式为
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">sudo apt<span class="hljs-attribute" style="box-sizing: border-box;">-get</span> install php5<span class="hljs-attribute" style="box-sizing: border-box;">-fpm</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


显然php-fpm能够帮我们解决1中遇到的问题。具体解决过程为:当我们的web服务器收到.php文件时,就让php-fpm把其解释(翻译)成html格式的文件(事实上php-fpm正是干这个事的),然后我们的web服务器将翻译出来的.html文件发给浏览器就万事大吉了。。


3.php-fpm与webserver交互问题

我想我在2中已经用最少的文字阐述清楚了当我们收到.php文件应该杂么办了。道理的确简单,问题在于我们如何才能让php-fpm帮我们解析我们想要翻译成.html文件的.php文件呢?(要知道php-fpm可不是人,它可听不懂人话的)。为了能与php-fpm愉快的合作,我们就得使用它能听得懂的语言(协议)。说道这fastcgi就正式登场了,没错php-fpm所能听的懂的语言正是fastcgi,我们可以通过fastcgi协议来和php-fpm进行交互来达成我们的目的


4.fastcgi协议

如果读者之前有学习过http或者TCP/IP协议,那么我想通过我接下来简单粗暴的讲解你一定能很快掌握此协议


(1)消息头(请求头)

对于fastcgi这种数据收发协议来说,它所发送的每次请求或是回复(我之后的叙述中叫它们为消息)都有一个可提取的公共部分就是FCGI_Header(请求头),及不管每次发送的是什么消息,都必须会有一个如下格式的请求头 

C语言格式(其支持各种语言)定义如下
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span>
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> version;              <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//版本</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> type;                 <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//操作类型</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> requestIdB1;          <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//请求id</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> requestIdB0;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> contentLengthB1;      <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//内容长度</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> contentLengthB0;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> paddingLength;        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//填充字节的长度</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> reserved;             <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//保留字节</span>
}FCGI_Header;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>


观察上面的消息请求头我们可以发现一个请求头只有8个字节大小,其每个字段的解释如下 

.version:用来表示FCGI的版本信息,如果是web服务器给php-fpm发送的消息,请求头中只需要将其置0就可以 

.type:此字段用来说明每次所发送消息的类型,其具体值可以为如下
type值具体含义
1在与php-fpm建立连接之后发送的第一个消息中的type值就得为1,用来表明此消息为请求开始的第一个消息
2异常断开与php-fpm的交互
3在与php-fpm交互中所发的最后一个消息中type值为此,以表明交互的正常结束
4在交互过程中给php-fpm传递环境参数时,将type设为此,以表明消息中包含的数据为某个name-value对
5web服务器将从浏览器接收到的POST请求数据(表单提交等)以消息的形式发给php-fpm,这种消息的type就得设为5
6php-fpm给web服务器回的正常响应消息的type就设为6
7php-fpm给web服务器回的错误响应设为7
还有一些其他的不常用的type值,我们这里就不提了,上述type值的详细含义可以在这里获得 
戳这里 

.requestId:此字段占俩个字节,它表示这某个特有的交互,因为php-fpm(可以理解为服务器)可以同时处理多个交互 

.contentLength:此字段也占2个字节,它用来表示此消息中的消息体中数据的长度(我们上面一直说的请求头也可以叫其消息头),我们可以据此在读消息时,能够知道读多长能读出一条完整的消息 

.paddingLength:填充长度的值,为了提高处理消息的能力,我们的每个消息大小都必须为8的倍数,此长度标示,我们在消息的尾部填充的长度 

.reserved:保留字段

以上便是我们对消息头8字节中每个字节所表达的含义的分析 

下图为php-fpm给web服务器传输的一个具体消息的消息头(8字节)内容 


 

.序列0(对应version字段)的数值为01,代表php-fpm的版本信息 

.序列1(对应type字段)的数值为03,根据上面对type值含义的解释,可以知道这个消息将标志这此次交互的结束 

.序列2,3 00,01说明此次交互的请求ID为01 

.序列4,5 00,08标示这在序列7之后的消息体的长度为8 

.序列6标示填充字节为0,及本身消息体以是8的字节了 

.序列7将消息的保留字节设为0 

通过上述具体实例,我想大家大概可以明白当我们得到fastcgi协议的一个消息头,我们能获取那些信息


(2)消息体(请求体)

(1)中我们简单介绍了一个消息的消息头,由于所有的消息都共用这个消息头,所以介绍起来也简单,但是消息体就不同了。对于请求开始(及一次交互的第一个)的消息,有其自己的消息体格式,对于请求结束(一次交互的最后一个)的消息,有其自己的消息体格式,对于传递PARAMS参数……消息头type字段标示的消息类型不同,对应的消息体的格式就可能不同 

接下来我会根据type值的不同来介绍各类消息体结构


1.type为1

读者对照上面介绍的type值的含义可知,此类消息为交互刚开始所发的第一个消息,其消息体结构c定义如下
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span>
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> roleB1;       <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//web服务器所期望php-fpm扮演的角色,具体取值下面有</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> roleB0;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> flags;        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//确定php-fpm处理完一次请求之后是否关闭</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> reserved[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>];  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//保留字段</span>
}FCGI_BeginRequestBody;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>


根据上述可知type值为1的消息(标识开始请求)的消息的消息体为固定大小8字节,其中各个字段的具体含义如下 

.role:此字段占2个字节,用来说明我们对php-fpm发起请求时,我们想让php-fpm为我们扮演什么角色(做什么,或理解为杂么做),其常见的3个取值如下:
role值具体含义
1最常用的值,php-fpm接受我们的http所关联的信息,并产生个响应
2php-fpm会对我们的请求进行认证,认证通过的其会返回响应,认证不通过则关闭请求
3过滤请求中的额外数据流,并产生过滤后的http响应
.flags:字段确定是否与php-fpm建立长连接,为1长连接,为0则在每次请求处理结束之后关闭连接 

.reserved:保留字段


2.type值为3

type值为3表示结束消息,其消息体的c定义如下
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span>
{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> appStatusB3;      <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//结束状态,0为正常</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> appStatusB2;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> appStatusB1;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> appStatusB0;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> protocolStatus;   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//协议状态</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> reserved[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>];
}FCGI_EndRequestBody;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>


同样我们可以看出结束消息体也为固定8字节大小 

其各字段的具体含义如下ph 

.appStatus:此字段共4个字节,用来表示结束状态,0为正常结束 

.protocolStatus:为协议所处的状态,0为正常状态 

.reserved:为保留字节


3.type为4

此值表示此消息体为传递PARAMS(环境参数),环境参数其实就是name-value对,我们可以使用自己定义的name-value传给php-fpm或者传递php-fpm已有的name-value对,以下为我们后面实例将会使用到的php-fpm以有的name-value对如下
namevalue
SCRIPT_FILENAMEvalue值为具体.php文件所处的位置php-fpm将根据value值找到所要处理的.php文件
REQUEST_METHODvalue值一般为GET,表示http请求的方式
好了回到主体,当我们要传递消息体为环境参数时,我们的消息体的格式如下
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameLengthB3; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* nameLengthB0 >> 7 == 0 */</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameLengthB2;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameLengthB1;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameLengthB0;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueLengthB3; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* nameLengthB0 >> 7 == 0 */</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueLengthB2;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueLengthB1;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueLengthB0;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameData[(B3 & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x7f</span>) << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">24</span>) + (B2 << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>) + (B1 << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>) + B0];
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueData[valueLength
((B3 & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x7f</span>) << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">24</span>) + (B2 << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>) + (B1 << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>) + B0];
} FCGI_NameValue;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>


可以看出消息体前8个字节为固定的,其字段具体含义为 

.nameLength:此字段占用4字节,用来说明name的长度 

.valueLength:此字段为4个字节,用来说明value的长度

前8个字节之后紧跟的为nameLength长度的name值,接着是valueLength长度的value值


4.type值为5,6,7

当消息为输入,输出,错误时,它的消息头之后便直接跟具体数据


(3)完整消息record

fastcgi将一个完整的消息称为record,我们每次发送的单位就是record。通过上面的介绍,我们可以总结出常见的记录格式
type值record
1header(消息头) + 开始请求体(8字节)
3header + 结束请求体(8字节)
4header + name-value长度(8字节) + 具体的name-value
5,6,7header + 具体内容


5.fastcgi协议使用实例

前面我们已经介绍了php-fpm的安装方法,其安装好之后,默认的通讯方式为unix本地域套接字通讯,具体查看
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">/etc/php5/fpm/pool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.d</span>/www<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.conf</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


截图如下 


 

而我们的接下来的实例与php-fpm为TCP通讯的方式,所以,我们得在这里改下配置,具体修改结果如下所示 


 

我将ip地址设成了127.0.0.1 监听端口设为9000 

修改之后需要重启php-fpm进程,如下
<code class="hljs bash has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">sudo</span> service php5-fpm restart</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


好了准备工作结束,此时编译运行这里的代码,我们就可以将内容为
<code class="hljs xml has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">html</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span>
<span class="php" style="box-sizing: border-box;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"><?php</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">echo</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello"</span>;
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">?></span></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span></code>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: