C语言编程题,实现一个简易的HTTP服务器,实现一个简易的HTTP服务器是一个很好的练习,可以帮助理解网络编程和HTTP协议的基本原理,使用C语言来实现这个服务器,它将能够处理基本的HTTP请求并返回简单的响应。

1、发送HTTP响应的函数

用于发送HTTP响应的函数。它向客户端发送一个包含状态行、响应头和HTML内容的HTTP响应。

HTTP/1.1 200 OK:表示服务器处理请求成功,返回状态码 200。

Content-Type: text/html:表示返回的数据类型是HTML格式。

Content-Length: 51:表示HTML内容的长度为 51 字节。

<html>...</html>:HTML内容,表示服务器返回的页面内容是一个简单的HTML页面。

write()向客户端发送数据。client_socket 是与客户端通信的套接字。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080  // 服务器监听的端口号
#define BUFFER_SIZE 1024

// 发送HTTP响应
void send_http_response(int client_socket) {
    char response[] =
        "HTTP/1.1 200 OK\r\n"
        "Content-Type: text/html\r\n"
        "Content-Length: 51\r\n"
        "\r\n"
        "<html><body><h1>Hello, C HTTP Server!</h1></body></html>";

    write(client_socket, response, sizeof(response) - 1);
}

2、创建绑定服务器套接字

socket()创建一个套接字。AF_INET是指定使用IPv4地址。SOCK_STREAM是指定使用TCP连接。0是协议自动选择为TCP。如果 socket() 返回 -1,表示创建失败,此时程序调用 perror() 输出错误信息并退出。bind()将套接字与服务器的IP地址和端口号绑定。如果绑定失败,程序输出错误信息并退出。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080  // 服务器监听的端口号
#define BUFFER_SIZE 1024


int main() {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    char buffer[BUFFER_SIZE];

    // 创建服务器套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("无法创建套接字");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;  // 监听所有网络接口
    server_addr.sin_port = htons(PORT);  // 端口号

    // 绑定套接字到指定的端口
    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("绑定失败");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    // 监听客户端连接请求
    if (listen(server_socket, 10) == -1) {
        perror("监听失败");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    printf("服务器启动,正在监听端口 %d...\n", PORT);
}

3、接受读取客户端请并响应

accept()接受客户端连接,并为该连接创建一个新的套接字 client_socket。如果接收失败,程序输出错误信息并继续等待下一个连接。调用之前定义的send_http_response()函数,向客户端发送HTTP响应。

while (1) {
    // 接受客户端连接
    client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
    if (client_socket == -1) {
        perror("接受客户端连接失败");
        continue;
    }

    // 清空缓冲区,接收客户端发送的数据
    memset(buffer, 0, BUFFER_SIZE);
    read(client_socket, buffer, BUFFER_SIZE - 1);
    printf("接收到的请求:\n%s\n", buffer);

    // 发送HTTP响应
    send_http_response(client_socket);

    // 关闭客户端连接
    close(client_socket);
}

// 关闭服务器套接字
close(server_socket);

4、完整代码

一个简易的HTTP服务器,可以根据自己的需求进行扩展和完善。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080  // 服务器监听的端口号
#define BUFFER_SIZE 1024

// 发送HTTP响应
void send_http_response(int client_socket) {
    char response[] =
        "HTTP/1.1 200 OK\r\n"
        "Content-Type: text/html\r\n"
        "Content-Length: 51\r\n"
        "\r\n"
        "<html><body><h1>Hello, C HTTP Server!</h1></body></html>";

    write(client_socket, response, sizeof(response) - 1);
}

int main() {
    int server_socket, client_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    char buffer[BUFFER_SIZE];

    // 创建服务器套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("无法创建套接字");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;  // 监听所有网络接口
    server_addr.sin_port = htons(PORT);  // 端口号

    // 绑定套接字到指定的端口
    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("绑定失败");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    // 监听客户端连接请求
    if (listen(server_socket, 10) == -1) {
        perror("监听失败");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    printf("服务器启动,正在监听端口 %d...\n", PORT);

    // 主循环,处理客户端连接
    while (1) {
        // 接受客户端连接
        client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
        if (client_socket == -1) {
            perror("接受客户端连接失败");
            continue;
        }

        // 清空缓冲区,接收客户端发送的数据
        memset(buffer, 0, BUFFER_SIZE);
        read(client_socket, buffer, BUFFER_SIZE - 1);
        printf("接收到的请求:\n%s\n", buffer);

        // 发送HTTP响应
        send_http_response(client_socket);

        // 关闭客户端连接
        close(client_socket);
    }

    // 关闭服务器套接字
    close(server_socket);

    return 0;
}

推荐文档

相关文档

大家感兴趣的内容

随机列表