#include <netinet/in.h> #include <netinet/ip.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h>

#define ECHO_PORT 9999 #define BUF_SIZE 4096

int close_socket(int sock) { if (close(sock)) { fprintf(stderr, "Failed closing socket.\n"); return 1; } return 0; }

int main(int argc, char* argv[]) { int sock, client_sock; ssize_t readret; socklen_t cli_size; struct sockaddr_in addr, cli_addr; char buf[BUF_SIZE];

fprintf(stdout, "----- Echo Server -----\n");

/* all networked programs must create a socket */
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
    fprintf(stderr, "Failed creating socket.\n");
    return EXIT_FAILURE;
}

addr.sin_family = AF_INET;
addr.sin_port = htons(ECHO_PORT);
addr.sin_addr.s_addr = INADDR_ANY;

/* servers bind sockets to ports---notify the OS they accept connections */
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)))
{
    close_socket(sock);
    fprintf(stderr, "Failed binding socket.\n");
    return EXIT_FAILURE;
}


if (listen(sock, 5))
{
    close_socket(sock);
    fprintf(stderr, "Error listening on socket.\n");
    return EXIT_FAILURE;
}

/* finally, loop waiting for input and then write it back */
while (1)
{
    cli_size = sizeof(cli_addr);
    if ((client_sock = accept(sock, (struct sockaddr *) &cli_addr,
                                &cli_size)) == -1)
    {
        close(sock);
        fprintf(stderr, "Error accepting connection.\n");
        return EXIT_FAILURE;
    }

    readret = 0;

    while((readret = recv(client_sock, buf, BUF_SIZE, 0)) >= 1)
    {
        // 解析消息
        char method[BUF_SIZE], uri[BUF_SIZE], version[BUF_SIZE];
        int n = sscanf(buf, "%s %s %s", method, uri, version);
        if (n != 3 || strcmp(version, "HTTP/1.1") != 0) {
            // 格式错误
            char response[] = "HTTP/1.1 400 Bad request\r\n\r\n";
            send(client_sock, response, strlen(response), 0);
            break;
        } else if (strcmp(method, "GET") == 0 || strcmp(method, "HEAD") == 0 || strcmp(method, "POST") == 0) {
            // Echo
            send(client_sock, buf, strlen(buf), 0);
            memset(buf, 0, BUF_SIZE);
            continue;
        } else {
            // 没实现
            char response[] = "HTTP/1.1 501 Not Implemented\r\n\r\n";
            send(client_sock, response, strlen(response), 0);
            break;
        }
    } 

    if (readret == -1)
    {
        close_socket(client_sock);
        close_socket(sock);
        fprintf(stderr, "Error reading from client socket.\n");
        return EXIT_FAILURE;
    }

    if (close_socket(client_sock))
    {
        close_socket(sock);
        fprintf(stderr, "Error closing client socket.\n");
        return EXIT_FAILURE;
    }
}

close_socket(sock);

return EXIT_SUCCESS;

}

C 语言实现 HTTP 服务器 - 解析多请求行消息

原文地址: https://www.cveoy.top/t/topic/n37z 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录