【网络编程】如何创建一个自己的并发服务器?

 

hello !大家好呀! 欢迎大家来到我的网络编程系列之如何创建一个自己的并发服务器,在这篇文章中,你将会学习到在Linux内核中如何创建一个自己的并发服务器,并且我会给出源码进行剖析,以及手绘UML图来帮助大家来理解,希望能让大家更能了解网络编程技术!!!

希望这篇文章能对你有所帮助,大家要是觉得我写的不错的话,那就点点免费的小爱心吧!

               

  如何创建高并发服务器

 对于如何创建一个自己的并发服务器,我们首先需要了解框架,就比如一个简单的shttpd服务器,其框架如图:

 在其中我们要知道这个框架能实现什么功能,有什么作用。

那么我们知道了这个微型服务器的大致框架,我们就要运用到代码上:

创建一个自己的并发 HTTP 服务器(shttpd)涉及到网络编程和 HTTP 协议的实现。以下是一个基本的步骤指南,用于在 Linux 系统上使用 C 语言和 POSIX 线程(pthread)创建一个简单的并发 HTTP 服务器。

大致服务过程如下:

那么如何实现呢? 

1. 确定服务器需求

明确你的服务器需要支持哪些 HTTP 方法(GET, POST 等),以及预期的并发量。

2. 选择合适的编程语言和库

我们将使用 C 语言和 POSIX 线程(pthread)库来创建一个多线程的 HTTP 服务器。

3. 创建 socket

使用 socket() 系统调用创建一个 TCP socket。

int serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if (serv_sock == -1) {perror("socket() error");exit(1);
}

4. 绑定地址和端口

使用 bind() 系统调用将 socket 绑定到一个地址和端口。

struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(PORT);if (bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {perror("bind() error");exit(1);
}

5. 监听连接

使用 listen() 系统调用开始监听连接。

if (listen(serv_sock, 5) == -1) {perror("listen() error");exit(1);
}

6. 创建线程处理函数

编写一个函数,用于线程处理客户端连接。这个函数将解析 HTTP 请求,并返回一个简单的 HTTP 响应。

void *handle_client(void *arg) {int clnt_sock = *(int *)arg;char request[1024];int read_len;// 读取 HTTP 请求read_len = read(clnt_sock, request, sizeof(request) - 1);if (read_len > 0) {request[read_len] = 0;printf("Received request: %s\n", request);// 发送 HTTP 响应char *response = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<html><body><h1>Hello, World!</h1></body></html>";write(clnt_sock, response, strlen(response));}close(clnt_sock);return NULL;
}

7. 接受连接并创建线程

使用 accept() 系统调用接受客户端连接,并为每个连接创建一个新的线程。

while (1) {struct sockaddr_in clnt_addr;socklen_t clnt_addr_size = sizeof(clnt_addr);int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);if (clnt_sock == -1) {perror("accept() error");continue;}pthread_t t_id;if (pthread_create(&t_id, NULL, handle_client, (void *)&clnt_sock) != 0) {perror("pthread_create() error");continue;}pthread_detach(t_id); // 使线程分离,不需要等待其终止
}

8. 关闭服务器 socket

在服务器终止前,关闭服务器 socket。

close(serv_sock);

9. 编译和运行

将上述代码保存为一个 .c 文件,例如 shttpd.c,然后使用以下命令编译:

gcc -o shttpd shttpd.c -lpthread

运行服务器:

./shttpd

以上过程分析可以总结为一下uml图的过程: 

 

注意事项

  • 上述代码仅用于演示目的,没有错误处理和资源清理。
  • 在生产环境中,应该添加适当的错误处理和日志记录。
  • 应确保服务器能够正确处理客户端断开连接的情况。
  • 考虑到安全性,可能需要实现更多的功能,如数据加密和身份验证。
  • 这个基本的示例仅支持 GET 方法,并且返回一个简单的 HTML 响应。实际应用中,你可能需要解析更多的 HTTP 请求头,支持其他 HTTP 方法,以及提供动态内容。

 

 

 根据以上一个简单并发服务器的结构分析,我们知道了如何实现一个最简单属于自己的服务器,

 

 

 

   好啦!到这里这篇文章就结束啦,关于实例代码中我写了很多注释,如果大家还有不懂得,可以评论区或者私信我都可以哦!! 感谢大家的阅读,我还会持续创造网络编程相关内容的,记得点点小爱心和关注哟!  

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

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

相关文章

素描石膏像:写实与抽象的美学对话

正文&#xff1a; 素描&#xff0c;作为绘画艺术的基础&#xff0c;承载着艺术家对世界的独特理解和表达。在素描石膏像的创作中&#xff0c;写实与抽象两种风格的碰撞&#xff0c;不仅展现了艺术家的技巧&#xff0c;更是一场美学的对话。 一、写实风格&#xff1a;细节的捕…

基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于HMM隐马尔可夫模型的金融数据预测算法.程序实现HMM模型的训练&#xff0c;使用训练后的模型进行预测。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运…

CentOS 7 文件权限管理详解

CentOS 7 文件权限管理详解 在 CentOS 7 系统中,文件权限管理是一项至关重要的任务,它确保了系统安全、数据完整性和用户隐私。本文将详细介绍 CentOS 7 中的文件权限管理,包括相关文件和命令的使用。 一、文件权限基础 在 Linux 系统中,每个文件和目录都有与之关联的权…

简单工厂模式抽象工厂模式

一.简单工厂模式 1.什么是工厂模式 工厂模式的核心就是把对象的生产过程交给工厂来完成&#xff0c;当外部需要一个对象时&#xff0c;由工厂提供接口来获取对象&#xff0c;这样一来即使生产对象的过程变了&#xff0c;仍然不影响外部对对象的获取和使用。 2.举个栗子 定义…

云计算笔记

RAID的组合方式 RAID0&#xff1a;多个硬盘同时工作&#xff0c;可提供性能&#xff0c;无冗余机制 RAID1&#xff1a;数据保存多份&#xff0c;提供冗余机制&#xff0c;性能受到影响 RAID3&#xff1a;存在数据盘和单独校验盘&#xff0c;数据写入 至数据盘后需要运算且将…

吃透2000-2024年600道真题和解析,科学高效通过2025年AMC8竞赛

为帮助孩子科学、有效备考AMC8竞赛&#xff0c;我整理了2000-2004年的全部AMC8真题&#xff08;完整版共600道&#xff0c;且修正了官方发布的原试卷中的少量bug&#xff09;&#xff0c;并且独家制作成多种在线练习&#xff0c;利用碎片化时间&#xff0c;8个多月的时间足以通…

Django中的实时通信:WebSockets与异步视图的结合【第167篇—实时通信】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在现代Web应用程序中&#xff0c;实时通信已经成为了必不可少的功能之一。无论是在线聊天、…

爆肝3k字!掌握Spring与Redis的高效交互:从Jedis到Spring Data Redis

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

甲辰年三月初九有感

甲辰年三月初九有感 雨多汇成洪&#xff0c;梅酸长几成&#xff1f; ​久旱微巨调&#xff0c;点积多少恒。 ​时光沙漏里&#xff0c;情境入己梦。 望山山外山&#xff0c;​登顶人为峰。

Spring Boot 多环境配置:YML 文件的三种高效方法

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

Linux内核之WRITE_ONCE用法实例(四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

单链表实现通讯录-三万字

声明 这一篇文章我会从单链表的概念&#xff0c;单链表的原理&#xff0c;一直到通讯录项目单链表的实现&#xff0c;再把单链表的专用题型系统的讲解一下&#xff08;文章较长&#xff09;。同时建议学习单链表之前可以学习一下顺序表&#xff0c;作为知识铺垫顺序表&#xf…

FreeRTOS 4.16作业

1、总结keil5下载代码和编译代码需要注意的事项 1&#xff09;使用STM32Cubemx创建工程 2&#xff09;先build编译排除错误 3&#xff09;点击魔术棒&#xff0c;选择Debug选项&#xff0c;找到使用的仿真器&#xff0c;选择ST-LINK仿真器&#xff0c;点击settings&#xff…

62、ARM/STM32开发板按键中断相关学习20240416

实现开发板上三个按键按下后触发中断&#xff0c;控制LED灯的亮灭。 【本次实验现象为&#xff1a;按键1&#xff08;key1&#xff09;控制开灯&#xff0c;key3控制关灯&#xff0c;key2按下LED灯闪烁五次】 代码&#xff1a; 头文件mykey.h: #ifndef __MYKEY_H__ #define…

【Java】@RequestMapping注解在类上使用

RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一。这个注解会将 HTTP 请求映射到控制器&#xff08;controller类&#xff09;的处理方法上。 Request Mapping 基础用法 在 Spring MVC 应用程序中&#xff0c;RequestDispatcher (在 Front Controller 之下) 这…

Google Guava第五讲:本地缓存实战及踩坑

本地缓存实战及踩坑 本文是Google Guava第五讲,先介绍为什么使用本地缓存;然后结合实际业务,讲解如何使用本地缓存、清理本地缓存,以及使用过程中踩过的坑。 文章目录 本地缓存实战及踩坑1、缓存系统概述2、缓存架构演变2.1、无缓存架构2.2、引入分布式缓存问题1:为什么选…

【HCIP学习】OSPF协议基础

一、OSPF基础 1、技术背景&#xff08;RIP中存在的问题&#xff09; RIP中存在最大跳数为15的限制&#xff0c;不能适应大规模组网 周期性发送全部路由信息&#xff0c;占用大量的带宽资源 路由收敛速度慢 以跳数作为度量值 存在路由环路可能性 每隔30秒更新 2、OSPF协议…

用ChatGPT轻松撰写出色论文

ChatGPT无限次数:点击直达 用ChatGPT轻松撰写出色论文 在当今信息爆炸的时代&#xff0c;写作是一项必不可少的技能。无论是学术论文、科技报道还是人文文学&#xff0c;写作都扮演着重要的角色。然而&#xff0c;写作并非每个人的强项&#xff0c;有时候我们会遇到写作灵感枯…

Python中的GIL(全局解释器锁):理解其对多线程编程的影响

Python中的GIL&#xff08;全局解释器锁&#xff09;&#xff1a;理解其对多线程编程的影响 在深入探讨Python编程的高级主题时&#xff0c;全局解释器锁&#xff08;GIL&#xff09;是一个不可忽视的概念。GIL是Python解释器中的一个互斥锁&#xff0c;它对多线程编程有着显著…

Spark-机器学习(2)特征工程之特征提取

在之前的文章中&#xff0c;我们了解我们的机器学习&#xff0c;了解我们spark机器学习中的MLIib算法库&#xff0c;知道它大概的模型&#xff0c;熟悉并认识它。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&a…