Boa是一款轻量级WebServer,向用户提供基于http协议的服务。

Boa接收和响应客户请求的流程

Boa作为一款http服务器,其最终要的功能就是接收和响应客户请求。

一般而言服务器程序都有相似的编程模型,所有服务器程序都必须完成下面的几件事情:

  1. 创建监听端口。监听端口相当于应用的门户,所有客户端都必须通过监听端口接入进来。
  2. 使用 accept 系统调用接入客户端。 在该步骤客户端就与服务器建立了一条可以用于全双工通信的管道(或称连接)。
  3. 使用 readwrite 系统调用,从客户端接收数据或向客户端发送数据。

下面我们来看下Boa具体是怎么完成上述三件事情的。

创建监听套接字

在进入main函数不久,我们就可以看到一条函数调用 server_s = create_server_socket();。 在这个函数里创建了套接字,并将其绑定了Boa的服务端口,然后通过 listen 完成了监听套接字的创建。

static int create_server_socket(void)
{
    int server_s;

    server_s = socket(SERVER_PF, SOCK_STREAM, IPPROTO_TCP);
    if (server_s == -1) {
        DIE("unable to create socket");
    }

    /* server socket is nonblocking */
    if (set_nonblock_fd(server_s) == -1) {
        DIE("fcntl: unable to set server socket to nonblocking");
    }

    /* close server socket on exec so CGIs can't write to it */
    if (fcntl(server_s, F_SETFD, 1) == -1) {
        DIE("can't set close-on-exec on server socket!");
    }

    /* reuse socket addr */
    if ((setsockopt(server_s, SOL_SOCKET, SO_REUSEADDR, (void *) &sock_opt,
                    sizeof (sock_opt))) == -1) {
        DIE("setsockopt");
    }

    /* Internet family-specific code encapsulated in bind_server()  */
    if (bind_server(server_s, server_ip, server_port) == -1) {
        DIE("unable to bind");
    }

    /* listen: large number just in case your kernel is nicely tweaked */
    if (listen(server_s, backlog) == -1) {
        DIE("unable to listen");
    }
    return server_s;
}

接入客户端连接

创建完监听套接字之后,在main函数中调用了 loop 。这时就正式进入了Boa的主循环了。 Boa的主循环总的来说就是不停的接入客户端连接,

数据结构

每一个请求的接入以及数据交互是由一个 request 结构管理的

struct request {                /* pending requests */
    ...

    int data_fd;                /* fd of data */
    int post_data_fd;           /* fd for post data tmpfile */
    int fd;                     /* client's socket fd */

    ...

    struct request *next;       /* next */
    struct request *prev;       /* previous */
};

本文作者ruleless, 欢迎评论、交流。
转载请务必标注出处: Boa


«Previous:   C语言中使用二维数组的另一种方式

»Next:         shell编程基础