⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server-sample.c

📁 跨平台windowsunixlinux的c语言编程解决方案
💻 C
字号:
/** * apr tutorial sample code * http://dev.ariel-networks.com/apr/ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <assert.h>#include <apr_general.h>#include <apr_file_io.h>#include <apr_strings.h>#include <apr_network_io.h>/* default listen port number */#define DEF_LISTEN_PORT		8081/* default socket backlog number. SOMAXCONN is a system default value */#define DEF_SOCKET_BACKLOG	SOMAXCONN/* default buffer size */#define BUFSIZE			4096/* useful macro */#define CRLF_STR		"\r\n"static apr_status_t do_listen(apr_socket_t **sock, apr_pool_t *mp);static int do_serv_task(apr_socket_t *serv_sock, apr_pool_t *mp);/** * Network server sample code * Just response to an HTTP GET request, but this is not a true HTTP server. * For example, you can test this program as follows, *  $ wget http://localhost:8081/etc/hosts * @remark Error checks omitted */int main(int argc, const char *argv[]){    apr_status_t rv;    apr_pool_t *mp;    apr_socket_t *s;/* listening socket */    apr_initialize();    apr_pool_create(&mp, NULL);    rv = do_listen(&s, mp);    if (rv != APR_SUCCESS) {        goto error;    }    while (1) {        apr_socket_t *ns;/* accepted socket */            rv = apr_socket_accept(&ns, s, mp);        if (rv != APR_SUCCESS) {            goto error;        }        /* it is a good idea to specify socket options for the newly accepted socket explicitly */        apr_socket_opt_set(ns, APR_SO_NONBLOCK, 0);        apr_socket_timeout_set(ns, -1);                if (!do_serv_task(ns, mp)) {            goto error;        }        apr_socket_close(ns);    }    apr_pool_destroy(mp);    apr_terminate();    return 0; error:    {        char errbuf[256];        apr_strerror(rv, errbuf, sizeof(errbuf));        printf("error: %d, %s\n", rv, errbuf);    }    apr_terminate();    return -1;}/** * Create a listening socket, and listen it. */static apr_status_t do_listen(apr_socket_t **sock, apr_pool_t *mp){    apr_status_t rv;    apr_socket_t *s;    apr_sockaddr_t *sa;        rv = apr_sockaddr_info_get(&sa, NULL, APR_INET, DEF_LISTEN_PORT, 0, mp);    if (rv != APR_SUCCESS) {        return rv;    }        rv = apr_socket_create(&s, sa->family, SOCK_STREAM, APR_PROTO_TCP, mp);    if (rv != APR_SUCCESS) {        return rv;    }    /* it is a good idea to specify socket options explicitly.     * in this case, we make a blocking socket as the listening socket */    apr_socket_opt_set(s, APR_SO_NONBLOCK, 0);    apr_socket_timeout_set(s, -1);    apr_socket_opt_set(s, APR_SO_REUSEADDR, 1);/* this is useful for a server(socket listening) process */    rv = apr_socket_bind(s, sa);    if (rv != APR_SUCCESS) {        return rv;    }    rv = apr_socket_listen(s, DEF_SOCKET_BACKLOG);    if (rv != APR_SUCCESS) {        return rv;    }    *sock = s;    return rv;}/** * Response a file content as a simple HTTP response protocol. * We assume that the request's first line is 'GET file-path HTTP/1.x' */static int do_serv_task(apr_socket_t *sock, apr_pool_t *mp){    int is_firstline = TRUE;    const char *filepath = NULL;    /* read all inputs from the client */    /* XXX This is not a precise parser of HTTP requests.     * Don't misunderstand that apr_socket_recv() returns a line. It just returns a chunk of bytes */    while (1) {	char buf[BUFSIZE];	apr_size_t len = sizeof(buf) - 1;/* -1 for a null-terminated */	apr_status_t rv = apr_socket_recv(sock, buf, &len);	if (rv == APR_EOF || len == 0) {	    break;        }        buf[len] = '\0';/* apr_socket_recv() doesn't return a null-terminated string */                if (is_firstline) {            char **tokens;            apr_tokenize_to_argv(buf, &tokens, mp);            if (tokens[0] && tokens[1] && strcmp(tokens[0], "GET") == 0) {                filepath = tokens[1];            }            is_firstline = FALSE;        }        if (strstr(buf, CRLF_STR CRLF_STR)) {/* expect the end of the request. no guarantee */            break;        }    }    if (filepath) {        apr_status_t rv;        apr_file_t *fp;                if ((rv = apr_file_open(&fp, filepath, APR_READ, APR_OS_DEFAULT, mp)) == APR_SUCCESS) {            const char *resp_hdr;            apr_size_t len;            const char *resp_body;            apr_finfo_t finfo;            apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);                        resp_hdr = apr_psprintf(mp, "HTTP/1.0 200 OK" CRLF_STR "Content-Length: %" APR_OFF_T_FMT CRLF_STR CRLF_STR, finfo.size);            len = strlen(resp_hdr);            apr_socket_send(sock, resp_hdr, &len);                        resp_body = apr_palloc(mp, finfo.size);            len = finfo.size;            apr_file_read(fp, (void*)resp_body, &len);            apr_socket_send(sock, resp_body, &len);                        return TRUE;        }    }        /* error case */    {        const char *resp_hdr = "HTTP/1.0 404 Not Found" CRLF_STR CRLF_STR;        apr_size_t len = strlen(resp_hdr);        apr_socket_send(sock, resp_hdr, &len);        return TRUE;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -