白骑士的C语言教学实战项目篇 4.4 简单HTTP服务器

        在本项目中,我们将设计并实现一个简单的HTTP服务器,涵盖网络编程基础、HTTP协议解析、多线程处理请求。通过这个项目,我们可以更加深入地了解网络编程、HTTP协议以及多线程编程的基本概念和实现方法。

网络编程基础

        网络编程是计算机科学中的一个重要领域,涉及到通过网络进行数据传输和通信。在C语言中,我们可以使用套接字(socket)来实现网络通信。套接字是网络通信的基本单元,提供了在不同计算机之间进行数据传输的机制。以下是使用套接字实现一个简单的TCP服务器的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080
#define BUFFER_SIZE 1024void handleClient(int clientSocket) {char buffer[BUFFER_SIZE];int bytesRead;// 读取客户端请求bytesRead = read(clientSocket, buffer, BUFFER_SIZE - 1);if (bytesRead < 0) {perror("读取错误");close(clientSocket);return;}buffer[bytesRead] = '\0';printf("客户端请求:\n%s\n", buffer);// 发送HTTP响应const char *response = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n""<html><body><h1>Hello, World!</h1></body></html>";write(clientSocket, response, strlen(response));// 关闭客户端套接字close(clientSocket);
}int main() {int serverSocket, clientSocket;struct sockaddr_in serverAddr, clientAddr;socklen_t addrLen = sizeof(clientAddr);// 创建套接字serverSocket = socket(AF_INET, SOCK_STREAM, 0);if (serverSocket < 0) {perror("套接字创建失败");exit(EXIT_FAILURE);}// 绑定地址和端口serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = INADDR_ANY;serverAddr.sin_port = htons(PORT);if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {perror("绑定失败");close(serverSocket);exit(EXIT_FAILURE);}// 监听连接if (listen(serverSocket, 5) < 0) {perror("监听失败");close(serverSocket);exit(EXIT_FAILURE);}printf("服务器正在运行,等待连接...\n");while (1) {// 接受客户端连接clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &addrLen);if (clientSocket < 0) {perror("连接接受失败");close(serverSocket);exit(EXIT_FAILURE);}// 处理客户端请求handleClient(clientSocket);}// 关闭服务器套接字close(serverSocket);return 0;
}

HTTP协议解析

        HTTP(HyperText Transfer Protocol)是用于在Web浏览器和Web服务器之间传输数据的协议。在本项目中,我们将实现一个简单的HTTP服务器,能够解析HTTP请求并返回HTTP响应。HTTP请求包括请求行、请求头和请求体,服务器需要解析这些内容并根据请求类型做出相应的响应。

多线程处理请求

        为了提高服务器的性能和响应速度,我们可以使用多线程来处理多个客户端请求。每当有新的客户端连接时,服务器可以创建一个新的线程来处理该连接。以下是使用多线程处理客户端请求的示例代码:

#include <pthread.h>// 线程处理函数
void *threadFunction(void *arg) {int clientSocket = *(int *)arg;handleClient(clientSocket);free(arg);return NULL;
}int main() {int serverSocket, *clientSocket;struct sockaddr_in serverAddr, clientAddr;socklen_t addrLen = sizeof(clientAddr);// 创建套接字serverSocket = socket(AF_INET, SOCK_STREAM, 0);if (serverSocket < 0) {perror("套接字创建失败");exit(EXIT_FAILURE);}// 绑定地址和端口serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = INADDR_ANY;serverAddr.sin_port = htons(PORT);if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {perror("绑定失败");close(serverSocket);exit(EXIT_FAILURE);}// 监听连接if (listen(serverSocket, 5) < 0) {perror("监听失败");close(serverSocket);exit(EXIT_FAILURE);}printf("服务器正在运行,等待连接...\n");while (1) {// 接受客户端连接clientSocket = malloc(sizeof(int));*clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &addrLen);if (*clientSocket < 0) {perror("连接接受失败");close(serverSocket);exit(EXIT_FAILURE);}// 创建新线程处理客户端请求pthread_t threadId;if (pthread_create(&threadId, NULL, threadFunction, clientSocket) != 0) {perror("线程创建失败");close(*clientSocket);free(clientSocket);}// 分离线程pthread_detach(threadId);}// 关闭服务器套接字close(serverSocket);return 0;
}

总结

        通过本项目,我们实现了一个简单的HTTP服务器,涵盖了网络编程基础、HTTP协议解析、多线程处理请求等模块。这个项目不仅让我们掌握了C语言中网络编程和多线程编程的基本方法,还提升了我们对HTTP协议的理解。在实际应用中,可以根据需要扩展服务器的功能,例如添加更多的HTTP请求处理逻辑,或使用更高级的多线程和网络编程技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/868442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年电脑监控软件排行榜(真实测评推荐七款电脑监控软件)

在信息化快速发展的今天&#xff0c;企业对员工电脑活动的监控变得尤为重要。有效的电脑监控软件不仅可以提升员工的工作效率&#xff0c;还能防止信息泄露&#xff0c;保障企业的数据安全。本文将介绍几款知名的电脑监控软件&#xff0c;并对其特点进行详细分析&#xff0c;帮…

java中函数式接口一般什么时候使用,并写一下详细的代码实例

在Java中&#xff0c;函数式接口&#xff08;Functional Interface&#xff09;主要用于支持Lambda表达式和方法引用&#xff0c;从而简化代码、提高可读性和可维护性。函数式接口是指仅包含一个抽象方法的接口&#xff0c;这样的接口可以通过Lambda表达式来实例化&#xff0c;…

DMException: 变量空间溢出,解决达梦数据库报错问题

达梦报错 Caused by: dm.jdbc.driver.DMException: 变量空间溢出 at dm.jdbc.driver.DBError.throwException(SourceFile:715) ~[DmJdbcDriver18.jar:- 8.1.3.100 - Production] at dm.jdbc.a.a.y.l(SourceFile:619) ~[DmJdbcDriver18.jar:- 8.1.3.100 - Production] …

笔记本电脑投屏怎么操作?一看就会!

日常工作或办公都会用到笔记本电脑&#xff0c;但很多新手用户不知道笔记本电脑的投屏要怎么操作&#xff1f;接下来系统之家给大家介绍三种简单的操作方法&#xff0c;帮助大家轻松完成笔记本电脑投屏投屏操作&#xff0c;从而满足自己的办公或学习使用需求。 方法一 1. 直接W…

Django QuerySet对象,exclude()方法

模型参考上一章内容&#xff1a; Django QuerySet对象&#xff0c;filter()方法-CSDN博客 exclude()方法&#xff0c;用于排除符合条件的数据。 1&#xff0c;添加视图函数 Test/app11/views.py from django.shortcuts import render from .models import Postdef index(re…

Eclipse运行main函数报 launch error

右键run as java application&#xff0c;运行main函数的时候报launch error 解决方式&#xff1a;文件右键run configurations 旧的是Project JRE&#xff0c;改成下图这个样子

python(opencv2、PIL)将图片透明背景转换成白色背景的两种方法

方法一&#xff1a;使用OpenCV的函数封装 pip install opencv-pythonimport cv2 import numpy as npdef convert_transparent_to_white_opencv(input_image_path, output_image_path):"""将透明背景的图片转换为白色背景&#xff0c;使用OpenCV实现。参数&…

服务器的分类有哪些

1、根据体系结构不同&#xff0c;服务器可以分成两大重要的类别&#xff1a;IA架构服务器和RISC架构服务器。   这种分类标准得主要依据是两种服务器采用得处理器体系结构不同。RISC架构服务器采用得CPU是所谓的精简指令集的处理器&#xff0c;精简指令集CPU的主要特点是采用…

Windows7彻底卸载mysql

1.控制面板卸载mysql 2.删除C:\Program Files\MySQL 3.删除C:\用户\Administrator\App Data\Roaming\MySQL”(App Data默认隐藏&#xff0c;需要在文件夹和搜索选项中勾选显示文件夹),为了删除的更彻底&#xff0c;可以直接在计算机全盘搜索MySQL关键字&#xff0c;将所有找到…

华为机试HJ53杨辉三角的变形

华为机试HJ53杨辉三角的变形 题目&#xff1a; 求杨辉三角中第n行第一个偶数出现的位置。 想法&#xff1a; 杨辉三角中存在规律&#xff0c;除了第一行与第二行没有偶数外&#xff0c;从第三行开始第一个偶数出现的位置以&#xff08;2&#xff0c;3&#xff0c;2&#xf…

mamba如何解决version `GLIBCXX_3.4.29‘ not found的问题

参考 如何解决version GLIBCXX_3.4.29‘ not found的问题_glibcxx not found-CSDN博客 用mamba时&#xff0c;出现报错 ImportError: /lib/x86_64-linux-gnu/libstdc.so.6: version GLIBCXX_3.4.29 not found 解决 #查找系统中的许多libstdc.so.6 sudo find / -name libstd…

软件测试下的AI之路(5)

😏作者简介:博主是一位测试管理者,同时也是一名对外企业兼职讲师。 📡主页地址:【Austin_zhai】 🙆目的与景愿:旨在于能帮助更多的测试行业人员提升软硬技能,分享行业相关最新信息。 💎声明:博主日常工作较为繁忙,文章会不定期更新,各类行业或职场问题欢迎大家…

实现不同的数据库之间的同步方式

第一种 实时同步 针对实时性要求比较高的场景可以使用canal中间件实现&#xff0c;我们内部的大数据项目中也有用dataX的。 canal 的主要用途是基于mysql数据库增量日志解析&#xff0c;并能提供新增量数据订阅和消费&#xff0c;从而实现数据同步。其主要是基于mysql 的binlo…

多数据库支持在PHP框架中的实现策略与实践

在现代Web开发中&#xff0c;随着应用规模的扩大和业务需求的多样化&#xff0c;单一数据库往往难以满足所有需求。多数据库支持&#xff0c;即在一个应用程序中使用多个数据库系统&#xff0c;已经成为许多项目的标准配置。本文将详细介绍如何在PHP框架中实现多数据库支持&…

QT中常用英语单词

Qt (.n): 一个跨平台的C应用程序开发框架&#xff0c;广泛用于开发GUI应用程序。Widget (.n): 在Qt中&#xff0c;一个widget指的是一个可视化的用户界面元素&#xff0c;如按钮、文本框等。Signal and Slot (.n): Qt特有的通信机制。Signal是某个特定事件发生时发出的信号&…

Unity之Text组件换行\n没有实现+动态中英互换

前因:文本中的换行 \n没有换行而是打印出来了,解决方式 因为unity会默认把\n替换成\\n 面板中使用富文本这个选项啊 没有用 m_text.text = m_text.text.Replace("\\n", "\n"); ###动态中英文互译 using System.Collections; using System.Collections…

20240708 多模态大模型

参考网站&#xff1a; 微软Florence-2官宣开源&#xff0c;一统视觉基础模型&#xff01;华人团队联手打造 自监督学习修炼之MoCov1与MoCov2 - 知乎 CLIP图像编码resnet50和transformer区别 CLIP (Contrastive Language-Image Pre-training) 是一个结合了图像和文本的跨模态…

顺序表与链表

前言&#xff1a; 顺序表和链表是属于数据结构中比较基础的知识&#xff0c;我们需要对其进行掌握。在JAVA原生标准库中分别为ArrayList和LinkedList。下图是整个数据结构之间的结构框图 1.ArrayList 背后用来存储数据的是一个数组&#xff0c;所以用ArrayList来进行相关操作…

【ai】决策树

决策树 决策树是一种监督学习算法,主要用于分类和回归任务。它通过对数据进行树状结构的分割来进行预测。决策树的主要优点包括易于理解和解释、处理数值型和分类型数据的能力以及对特征缩放不敏感。以下是决策树的基本概念和主要应用。决策树的基本概念 节点(Node): 根节…

前端面试题23(css3)

关于CSS3的面试题&#xff0c;我们可以从多个维度来探讨&#xff0c;包括但不限于选择器、盒模型、布局技术、动画与过渡、响应式设计等。下面我会列举一些典型的CSS3面试问题&#xff0c;并尽可能提供详细的解答或示例代码。 1. CSS3中新增了哪些选择器&#xff1f; 答案: C…