实战案例3:C语言实现的HTTP服务器

简介: 实战案例3:C语言实现的HTTP服务器

实战案例3:C语言实现的HTTP服务器

详细解析如何用C语言实现一个基本的HTTP服务器,处理GET和POST请求。

 

 

创建一个简单的HTTP服务器以处理GET和POST请求在C语言中是一个很好的学习项目,因为它涉及到了网络编程、字符串处理以及HTTP协议的基础知识。下面,我将逐步介绍如何使用C语言和socket编程来实现这样的服务器。

1. 准备工作

首先,确保你的系统上安装了C编译器,如GCC。此外,你需要了解socket编程的基本概念,包括TCP/IP协议栈、套接字(sockets)等。

2. 编写HTTP服务器的基本框架

2.1 包含必要的头文件

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <netinet/in.h>

#include <sys/socket.h>

2.2 初始化socket

int create_socket(int port) {

int server_fd, yes = 1;

struct sockaddr_in address;

int opt = 1;

 

if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {

perror("socket failed");

exit(EXIT_FAILURE);

}

 

if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {

perror("setsockopt");

exit(EXIT_FAILURE);

}

 

address.sin_family = AF_INET;

address.sin_addr.s_addr = INADDR_ANY;

address.sin_port = htons(port);

 

if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {

perror("bind failed");

exit(EXIT_FAILURE);

}

 

if (listen(server_fd, 3) < 0) {

perror("listen");

exit(EXIT_FAILURE);

}

 

return server_fd;

}

2.3 处理HTTP请求

你需要解析传入的HTTP请求,并根据请求类型(GET或POST)来响应。这里为了简化,我们仅处理GET请求,并发送一个简单的HTML页面作为响应。

void handle_request(int sock) {

char buffer[1024] = {0};

read(sock, buffer, 1024);

 

printf("HTTP request:\n%s\n", buffer);

 

// 这里假设只处理GET请求

if (strstr(buffer, "GET / ") != NULL) {

const char *http_response = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n<html><body><h1>Hello, World!</h1></body></html>";

write(sock, http_response, strlen(http_response));

}

 

close(sock);

}

2.4 主函数

int main(int argc, char *argv[]) {

int server_fd, new_socket;

struct sockaddr_in address;

int opt = sizeof(address);

 

if (argc != 2) {

fprintf(stderr, "Usage: %s <port>\n", argv[0]);

exit(EXIT_FAILURE);

}

 

server_fd = create_socket(atoi(argv[1]));

 

while (1) {

if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&opt)) < 0) {

perror("accept");

exit(EXIT_FAILURE);

}

 

// 创建子进程处理请求

pid_t pid = fork();

 

if (pid == 0) {

// 子进程

close(server_fd);

handle_request(new_socket);

exit(0);

} else {

// 父进程

close(new_socket);

}

}

 

return 0;

}

3. 编译和运行

将上述代码保存为http_server.c,并使用GCC编译:

gcc http_server.c -o http_server

然后,运行服务器:

./http_server 8080

在浏览器中访问http://localhost:8080/,你应该能看到“Hello, World!”的页面。

 

 

实战案例3:C语言实现的HTTP服务器(扩展)

在构建一个简单的HTTP服务器时,我们需要处理网络通信、请求解析以及响应生成等多个技术环节。以下是一个详细的步骤和代码示例,用于创建一个能够处理GET请求的HTTP服务器,并返回“Hello, World!”的HTML页面。此代码将基于C语言,使用标准的socket编程技术。

1. 包含必要的头文件

首先,我们需要包含处理网络通信和字符串操作所需的头文件。

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

2. 定义常量和全局变量

为了方便管理,我们定义一些常量来表示网络地址族、套接字类型以及HTTP响应等。

#define PORT 8080

#define BUFFER_SIZE 1024

 

const char* http_response =

"HTTP/1.1 200 OK\r\n"

"Content-Type: text/html\r\n"

"\r\n"

"<html><body><h1>Hello, World!</h1></body></html>";

3. 创建套接字函数

接下来,我们编写一个函数来创建并配置套接字。

int create_socket(int port) {

int server_fd, yes = 1;

struct sockaddr_in address;

int opt = 1;

 

if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {

perror("socket failed");

exit(EXIT_FAILURE);

}

 

if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) < 0) {

perror("setsockopt");

close(server_fd);

exit(EXIT_FAILURE);

}

 

address.sin_family = AF_INET;

address.sin_addr.s_addr = INADDR_ANY;

address.sin_port = htons(port);

 

if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {

perror("bind failed");

close(server_fd);

exit(EXIT_FAILURE);

}

 

if (listen(server_fd, 3) < 0) {

perror("listen");

close(server_fd);

exit(EXIT_FAILURE);

}

 

return server_fd;

}

4. 处理HTTP请求的函数

然后,我们定义一个函数来接收HTTP请求,并发送响应。

void handle_request(int sock) {

char buffer[BUFFER_SIZE] = {0};

int valread = read(sock, buffer, BUFFER_SIZE);

printf("HTTP request:\n%s\n", buffer);

 

if (strstr(buffer, "GET / ") != NULL) {

write(sock, http_response, strlen(http_response));

} else {

// 可以处理其他类型的HTTP请求或发送错误响应

const char* error_response =

"HTTP/1.1 404 Not Found\r\n"

"Content-Type: text/plain\r\n"

"\r\n"

"404 Not Found";

write(sock, error_response, strlen(error_response));

}

 

close(sock);

}

5. 主函数

最后,我们在主函数中启动服务器,并等待连接。

int main(int argc, char *argv[]) {

int server_fd = create_socket(PORT);

struct sockaddr_in client_addr;

socklen_t len = sizeof(client_addr);

 

printf("Server is listening on port %d...\n", PORT);

 

while (1) {

int sock = accept(server_fd, (struct sockaddr *)&client_addr, &len);

if (sock < 0) {

perror("accept failed");

continue;

}

 

printf("Accepted new connection from %s:%d\n",

inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

 

// 处理

 

相关文章
|
4月前
|
人工智能 JavaScript API
零基础构建MCP服务器:TypeScript/Python双语言实战指南
作为一名深耕技术领域多年的博主摘星,我深刻感受到了MCP(Model Context Protocol)协议在AI生态系统中的革命性意义。MCP作为Anthropic推出的开放标准,正在重新定义AI应用与外部系统的交互方式,它不仅解决了传统API集成的复杂性问题,更为开发者提供了一个统一、安全、高效的连接框架。在过去几个月的实践中,我发现许多开发者对MCP的概念理解透彻,但在实际动手构建MCP服务器时却遇到了各种技术壁垒。从环境配置的细节问题到SDK API的深度理解,从第一个Hello World程序的调试到生产环境的部署优化,每一个环节都可能成为初学者的绊脚石。因此,我决定撰写这篇全面的实
913 67
零基础构建MCP服务器:TypeScript/Python双语言实战指南
|
1月前
|
弹性计算 人工智能 前端开发
在阿里云ECS上部署n8n自动化工作流:U2实例实战
本文介绍如何在阿里云ECS的u2i/u2a实例上部署开源工作流自动化平台n8n,利用Docker快速搭建并配置定时任务,实现如每日抓取MuleRun新AI Agent并推送通知等自动化流程。内容涵盖环境准备、安全组设置、实战案例与优化建议,助力高效构建低维护成本的自动化系统。
429 5
|
5月前
|
C# 图形学 开发者
Unity开发中使用UnityWebRequest从HTTP服务器下载资源。
总之,UnityWebRequest就是游戏开发者手中的万能钓鱼竿,既可以获取文本数据,也能钓上图片资源,甚至是那声音的涟漪。使用UnityWebRequest的时候,你需要精心准备,比如确定URL、配置请求类型和头信息;发起请求;巧妙处理钓获的数据;还需要机智面对网络波澜,处理各种可能出现的错误。按照这样的过程,数据的钓取将会是一次既轻松愉快也效率高效的编程钓鱼之旅。
280 18
|
3月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
4月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
4月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
390 0
|
4月前
|
Web App开发 缓存 数据安全/隐私保护
Django全栈实战:HTTP状态码与业务状态码的分层设计与实战应用
HTTP状态码是服务器响应请求的3位数字代码,分为1xx(信息)、2xx(成功)、3xx(重定向)、4xx(客户端错误)、5xx(服务器错误)。业务状态码则用于描述具体业务逻辑结果,常在响应体中返回。二者在前后端交互中有不同用途和处理方式。本文还介绍了如何在Django项目中设计并使用业务状态码。
413 0
|
1月前
|
弹性计算 运维 安全
阿里云轻量应用服务器与云服务器ECS啥区别?新手帮助教程
阿里云轻量应用服务器适合个人开发者搭建博客、测试环境等低流量场景,操作简单、成本低;ECS适用于企业级高负载业务,功能强大、灵活可扩展。二者在性能、网络、镜像及运维管理上差异显著,用户应根据实际需求选择。
221 10
|
1月前
|
运维 安全 Ubuntu
阿里云渠道商:服务器操作系统怎么选?
阿里云提供丰富操作系统镜像,涵盖Windows与主流Linux发行版。选型需综合技术兼容性、运维成本、安全稳定等因素。推荐Alibaba Cloud Linux、Ubuntu等用于Web与容器场景,Windows Server支撑.NET应用。建议优先选用LTS版本并进行测试验证,通过标准化镜像管理提升部署效率与一致性。