最近在看《linux高性能服务器编程》,在此做个日记,以激励自己,同时分享于有需要的朋友。
1. 我们简单模拟HTTP请求的读取和分析
判断HTTP头部结束的依据是遇到一个空行,该空行仅包含一对回车换行符<CR><LF> 。如果一次读操作没有读入HTTP请求的整个头部, 即没有遇到空行, 那么我们必须等待客户继续写数据并再次读入。
因此,我们每完成一次读操作,就要分析新读入的数据中是否有空行。在寻找空行的过程中,我们可以同时完成对整个HTTP请求头部的分析,以提高效率。
2. 客户端用telnet测试
请求如下:
Host: www.xxx.com
other...
3. 代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 4096
//主状态机
enum CHECK_STATE
{
CHECK_STATE_REQUESTLINE = 0, //当前正在分析请求行
CHECK_STATE_HEADER, //当前正在分析头部字段
CHECK_STATE_CONTENT
};
//从状态机,行的读取状态
enum LINE_STATUS
{
LINE_OK = 0, //读到完整行
LINE_BAD, //行出错
LINE_OPEN //行数据不完整
};
//HTTP请求结果
enum HTTP_CODE
{
NO_REQUEST, //请求不完整, 需要继续读取客户端数据
GET_REQUEST, //获得了完整的客户请求
BAD_REQUEST, //客户请求有语法错误
FORBIDDEN_REQUEST, //客户对资源没有足够的访问权限
INTERNAL_ERROR, //服务器内部错误
CLOSED_CONNECTION //客户端已关闭连接
};
//发给客户端的应答报文(简化版)
static const char *szret[] = {"I get a correct result\n",
"Something wrong\n"};
LINE_STATUS parse_line(char *buffer,