Linuxwebserver项目

1.主函数mian

signal(SIGPIPE,SIG_IGN);
    char pwd_path[256]="";记录工作目录
    char * path = getenv("PWD");获取当前目录工作路径
    ///home/itheima/share/bjc++34/07day/web-http
    strcpy(pwd_path,path);字符串复制函数
    strcat(pwd_path,"/web-http");两个字符型连接起来
    chdir(pwd_path);改变当前工作路径

int lfd = tcp4bind(PORT,NULL);创建lfd,并且绑定,

Listen(lfd,128);监听

int epfd = epoll_create(1);创建红黑树,创建句柄

struct epoll_event ev,evs[1024];创建事件结构体和事件集合
 ev.data.fd = lfd;结构体内部的文件描述
 ev.events = EPOLLIN;定义事件为读事件
 epoll_ctl(epfd,EPOLL_CTL_ADD,lfd,&ev);将lfd上树,

while(1)循环监听
    {
        int nready = epoll_wait(epfd,evs,1024,-1);去监听集合
        if(nready < 0)报错
        {
            perror("");
            break;
        }
        else我们需要查找集合那个发生变化
        {
            for(int i=0;i<nready;i++)
            {
                printf("001\n");
                if(evs[i].data.fd == lfd && evs[i].events & EPOLLIN)判断是否是lfd,且是读事件
                {
                    struct sockaddr_in cliaddr;构建客户端地址结构体
                    char ip[16]="";ip地址接收
                    socklen_t len = sizeof(cliaddr);地址长度
                    int cfd = Accept(lfd,(struct sockaddr*)&cliaddr,&len);提取新的cfd
                    printf("new client ip=%s port=%d\n",
                        inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,16),
                        ntohs(cliaddr.sin_port));并且打印出出ip和端口
                    int flag = fcntl(cfd,F_GETFL);需要设置cfd为非阻塞fcntl函数可以设置
                    flag |= O_NONBLOCK;设置标志位
                    fcntl(cfd,F_SETFL,flag);
                    ev.data.fd = cfd;将cfd上树
                    ev.events = EPOLLIN;事件是读事件
                    epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&ev);
                }
                else if(evs[i].events & EPOLLIN)//cfd变化
                {
                    read_client_request(epfd,&evs[i]);我们去调用这个函数读客户端请求

                }

            }
        }
    }

2.读客户端请求read_client_request函数

void read_client_request(int epfd ,struct epoll_event *ev)//句柄和事件
{char buf[1024]="";//读取一行,再把其他行读取,扔掉char tmp[1024]="";//int n = Readline(ev->data.fd, buf, sizeof(buf));if(n <= 0)//读取的是小于等于0代表关闭或者出错{printf("close or err\n");epoll_ctl(epfd,EPOLL_CTL_DEL,ev->data.fd,ev);下树close(ev->data.fd);关闭文件描述符return ;}printf("[%s]\n", buf);缓冲区数据打印出来int ret =0;返回值接收while(  (ret = Readline(ev->data.fd, tmp, sizeof(tmp))) >0);  //解析请求行 GET /a.txt  HTTP/1.1\R\N//char method[256]="";getchar content[256]="";/a.txtchar protocol[256]="";HTTP/1.1\R\Nsscanf(buf,"%[^ ] %[^ ] %[^ \r\n]",method,content,protocol);拆字符串空格拆分,printf("[%s]  [%s]  [%s]\n",method,content,protocol );打印出来//判断是否为get请求  get   GETif( strcasecmp(method,"get") == 0){//[GET]  [/%E8%8B%A6%E7%93%9C.txt]  [HTTP/1.1]拆解的字符char *strfile = content+1;strdecode(strfile,strfile);//GET / HTTP/1.1\R\Nif(*strfile == 0)//如果没有请求文件,默认当前目录strfile= "./";//判断请求的文件在不在struct stat s;if(stat(strfile,&s)< 0)//文件不存在{printf("file not fount\n");//先发送 报头(状态行 消息头 空行)send_header(ev->data.fd, 404,"NOT FOUND",get_mime_type("*.html"),0);调用//发送文件error.htmlsend_file(ev->data.fd,"error.html",ev,epfd,1);调用}else{//请求一个普通文件if(S_ISREG(s.st_mode)){printf("file\n");//先发送 报头(状态行 消息头 空行)send_header(ev->data.fd, 200,"OK",get_mime_type(strfile),s.st_size);//发送文件send_file(ev->data.fd,strfile,ev,epfd,1);}else if(S_ISDIR(s.st_mode))//请求是一个目录{printf("dir\n");//发送一个列表 网页send_header(ev->data.fd, 200,"OK",get_mime_type("*.html"),0);//发送header.htmlsend_file(ev->data.fd,"dir_header.html",ev,epfd,0);struct dirent **mylist=NULL;定义一个指针char buf[1024]="";缓冲区int len =0;长度int n = scandir(strfile,&mylist,NULL,alphasort);for(int i=0;i<n;i++){//printf("%s\n", mylist[i]->d_name);if(mylist[i]->d_type == DT_DIR)//如果是目录{len = sprintf(buf,"<li><a href=%s/ >%s</a></li>",mylist[i]->d_name,mylist[i]->d_name);}else{len = sprintf(buf,"<li><a href=%s >%s</a></li>",mylist[i]->d_name,mylist[i]->d_name);}send(ev->data.fd,buf,len ,0);发送数据free(mylist[i]);释放}free(mylist);释放send_file(ev->data.fd,"dir_tail.html",ev,epfd,1);发送文件}}}}

3.发送状态行函数send_header

void send_header(int cfd, int code,char *info,char *filetype,int length)
{	发送状态行char buf[1024]="";缓冲区int len =0;len = sprintf(buf,"HTTP/1.1 %d %s\r\n",code,info);字符串格式化send(cfd,buf,len,0);发送cfd中//发送消息头len = sprintf(buf,"Content-Type:%s\r\n",filetype);格式化send(cfd,buf,len,0);发送到cfd中if(length > 0){//发送消息头len = sprintf(buf,"Content-Length:%d\r\n",length);对长度处理send(cfd,buf,len,0);}//空行send(cfd,"\r\n",2,0);
}

4.发送文件send_file函数

void send_file(int cfd,char *path,struct epoll_event *ev,int epfd,int flag)
{int fd = open(path,O_RDONLY);只读打开路径,生成文件描述符if(fd <0)文件不存在报错{perror("");return ;}char buf[1024]="";定义一个缓冲区int len =0;长度while( 1){len = read(fd,buf,sizeof(buf));从缓冲区读if(len < 0)如果没有报错{perror("");break;}等于0跳出else if(len == 0){break;}else{int n=0;n =  send(cfd,buf,len,0);我们发送数据printf("len=%d\n", n);}}close(fd);关闭文件描述符//关闭cfd,下树if(flag==1){close(cfd);epoll_ctl(epfd,EPOLL_CTL_DEL,cfd,ev);}}

#define PORT 8889端口号,

上述就是实现webserver整体代码了

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

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

相关文章

《数据结构、算法与应用C++语言描述》- 平衡搜索树 -全网唯一完整详细实现插入和删除操作的模板类

平衡搜索树 完整可编译运行代码见&#xff1a;Github::Data-Structures-Algorithms-and-Applications/_34Balanced search tree 概述 本章会讲AVL、红-黑树、分裂树、B-树。 平衡搜索树的应用&#xff1f; AVL 和红-黑树和分裂树适合内部存储的应用。 B-树适合外部存储的…

[Ray Tracing: The Rest of Your Life] 笔记

前言 开年第一篇博客~ 整理了三四个小时才整理完orz。 这一部分是光线追踪三部曲的最后一部&#xff0c;主要介绍了蒙特卡洛积分、重要性采样等内容。场景上没有什么大的改变&#xff0c;基本上就是在Cornell Box中渲染的&#xff0c;本篇主要在加速收敛&#xff0c;提升渲染效…

LeetCode 2735. 收集巧克力【枚举】2043

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

【快速全面掌握 WAMPServer】09.如何在 WAMPServer 中安装 Composer

网管小贾 / sysadm.cc WAMPServer 的大名想必应该有不少人特别是新手小白们略有耳闻吧。 它是出自法国大神之手的一款 PHP 开发环境集成包&#xff0c;工作于 Windows 环境&#xff0c;类似于它这样的集成包在 Linux 平台上反正我是没找到&#xff0c;所以它应该算是对使用 Wi…

CollectionUtils

使用 CollectionUtils 类的常用方法 在Java开发中&#xff0c;我们经常需要对集合进行各种操作&#xff0c;而Apache Commons Collections库提供了一个方便的工具类 CollectionUtils&#xff0c;其中包含了许多实用的方法。在这篇博客中&#xff0c;我们将深入了解一些常用的方…

MIT线性代数笔记-第35讲-期末复习

目录 35.期末复习打赏 35.期末复习 已知一个矩阵 A A A满足 A x ⃗ [ 1 0 0 ] A \vec{x} \begin{bmatrix} 1 \\ 0 \\ 0 \end{bmatrix} Ax ​100​ ​无解且 A x ⃗ [ 0 1 0 ] A \vec{x} \begin{bmatrix} 0 \\ 1 \\ 0 \end{bmatrix} Ax ​010​ ​仅有一个解 (1)求 A A A的…

call的一点奇怪的使用

Object.prototype.hasOwnProperty.call(initModal, method) 解释&#xff1a; 在这个特定的代码中&#xff0c;它用于检查 initModal 对象是否具有名为 method 的属性。 Object.prototype.hasOwnProperty 是一个内置的 JavaScript 方法&#xff0c;它可以检查一个对象是否具有…

linux安装rabbitmq

文章目录 前言一、下载安装包二、erlang1.安装依赖2.解压3.安装4.环境变量5.验证 三、rabbitmq1.安装依赖2.解压3.新建目录4.rabbitmq.env.conf5.rabbitmq.conf6.环境变量7.启动8.验证9.停止 四、安装web1.安装插件2.访问控制台界面 五、开机启动1.编写脚本2.设置开机启动3.测试…

硬件安全模块 (HSM)、硬件安全引擎 (HSE) 和安全硬件扩展 (SHE)的区别

术语 硬件安全模块 (HSM) &#xff1a;Hardware Security Modules硬件安全引擎 (HSE) &#xff1a;Hardware Security Engines安全硬件扩展 (SHE) &#xff1a; Secure Hardware Extensions 介绍 在汽车行业中&#xff0c;硬件安全模块 (HSM)、硬件安全引擎 (HSE) 和安全硬件…

Android长按图标展示快捷方式

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {new Thread(() -> {// 获取ShortcutManager实例ShortcutManager shortcutManager getSystemService(ShortcutManager.class);// 创建要添加的快捷方式ShortcutInfo.Builder shortcutBuilder new ShortcutInfo.Bui…

Java中如何实现负载均衡策略

1. 引言 当在Java应用程序中需要处理负载均衡时&#xff0c;通常涉及到多个服务器或服务实例&#xff0c;以确保请求能够分散到这些实例上&#xff0c;从而提高系统性能、可用性和可伸缩性。实现负载均衡策略可以通过多种方法&#xff0c;包括基于权重、轮询、随机选择、最少连…

[蓝桥杯2020国赛]答疑

答疑 题目描述 有 n 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。 老师可以安排答疑的顺序&#xff0c;同学们要依次进入老师办公室答疑。 一位同学答疑的过程如下&#xff1a; 首先进入办公室&#xff0c;编号为 i 的同学需要 si​ 毫秒的时间。然后同学问…

大语言模型训练数据集

大语言模型的数据集有很多&#xff0c;以下是一些常用的&#xff1a; - 中文维基百科&#xff1a;这是一个包含大量中文文本的数据集&#xff0c;可用于训练中文语言模型。 - 英文维基百科&#xff1a;这是一个包含大量英文文本的数据集&#xff0c;可用于训练英文语言模型。 …

python脚本实现一次提取多个文件下的图片

problem formulation 有时候下载的数据集如下&#xff0c;就很烦&#xff0c;一个里面就一张图片 code import os import shutil# 定义源目录和目标目录 source_dir ./dataset/data/Detection destination_dir ./dataset/data/img# 确保目标目录存在&#xff0c;如果不存…

css原子化的框架Tailwindcss的使用教程(原始html和vue项目的安装与配置)

安装教程 中文官网教程 原始的HTML里面使用 新建文件夹npm init -y 初始化项目 安装相关依赖 npm install -D tailwindcss postcss-cli autoprefixer初始化两个文件 npx tailwindcss init -p根目录下新建src/style.css tailwind base; tailwind components; tailwind ut…

图神经网络--GNN从入门到精通

图神经网络--GNN从入门到精通 一、图的基本表示和特征工程1.1 什么是图1.2 图的基本表示1.3 图的性质--度&#xff08;degree)1.4 连通图&#xff0c;连通分量1.5有向图连通性1.6图直径1.7度中心性1.7特征中心性&#xff08; Eigenvector Centrality&#xff09;1.8中介中心性 …

CentOS 7 实战指南:目录操作命令详解

写在前面 想要在 CentOS 7 系统下更高效地进行目录操作吗&#xff1f;不要犹豫&#xff0c;在这里我为你准备了一篇精彩的技术文章&#xff01;这篇文章将带您深入了解 CentOS 7 下目录操作相关命令的使用方法。无论您是新手还是有一定经验的用户&#xff0c;这篇文章都将为您…

EasyNTS端口穿透服务新版本发布 0.8.7 增加隧道流量总数记录,可以知晓设备哪个端口耗费流量了

EasyNTS上云平台可通过远程访问内网应用&#xff0c;包含网络桥接、云端运维、视频直播等功能&#xff0c;极大地解决了现场无固定IP、端口不开放、系统权限不开放等问题。平台可提供一站式上云服务&#xff0c;提供直播上云、设备上云、业务上云、运维上云服务&#xff0c;承上…

金蝶云星空其他出库单,审核中/审批流中可以选择序列号设置

文章目录 其他出库单&#xff0c;审核中&#xff0c;审批流中可以选择序列号设置 其他出库单&#xff0c;审核中&#xff0c;审批流中可以选择序列号设置

创建型设计模式 - 抽象工厂模式 - JAVA

创建型设计模式 - 抽象工厂设计模式 一. 简介二. 列子2.1 定义电脑的抽象类和子类2.2 定义抽象工厂类和其实现类2.3 测试 三. 抽象工厂设计模式的好处四. 抽象工厂模式的案例 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续…