c语言提供后端,提供页面显示跳转服务

后端代码:

#define SERVER_IP_ADDR "0.0.0.0"  // 服务器IP地址
#define SERVER_PORT 8080          // 服务器端口号
#define BACKLOG 10
#define BUF_SIZE 8192
#define OK 1
#define ERROR 0

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>

const char* Server_name = "Server: Web Server 1.0 - BooLo\r\n";

int Server_Socket_Init(int port);
int Handle_Request_Message(char* message, int Socket);
int Judge_URI(char* URI, int Socket);
int Send_Ifon(int Socket, const char* sendbuf, int Length);
int Error_Request_Method(int Socket);
int Inquire_File(char* URI);
int File_not_Inquire(int Socket);
int Send_File(char* URI, int Socket);
const char* Judge_Method(char* method, int Socket);
const char* Judge_File_Type(char* URI, const char* content_type);
const char* Get_Data(const char* cur_time);
const char* Post_Value(char* message);
int Logo();

// 创建套接字函数
int Server_Socket_Init(int port){
    int ServerSock;
    struct sockaddr_in ServerAddr;

    // 创建套接字
    ServerSock = socket(AF_INET, SOCK_STREAM, 0);
    if(ServerSock < 0){
        perror("Failed to create socket!");
        exit(1);
    }

    // 配置服务器IP、端口信息
    memset(&ServerAddr, 0, sizeof(ServerAddr));
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(port);
    ServerAddr.sin_addr.s_addr = inet_addr(SERVER_IP_ADDR);

    // 绑定
    if(bind(ServerSock, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)) < 0){
        perror("Failed to bind stream socket!");
        exit(1);
    }

    return ServerSock;
}

// 处理浏览器发送的数据

int Handle_Request_Message(char* message, int Socket){

    int rval = 0;
    char Method[BUF_SIZE];
    char URI[BUF_SIZE];
    char Version[BUF_SIZE];

    if(sscanf(message, "%s %s %s", Method, URI, Version) != 3){
        printf("Request line error!\n");
        return ERROR;
    }

    printf("$$$ Method: %s, URI: %s, Version %s \n",Method, URI, Version);

    if(Judge_Method(Method, Socket) == ERROR){
        return ERROR;
    }else if(strcmp(Judge_Method(Method, Socket), "POST") == 0){
        Post_Value(message);
    }

    if(strcmp(URI, "/") == 0){
        strcpy(URI, "/ndex.html");
    }

    if(Judge_URI(URI, Socket) == ERROR){
        return ERROR;
    } else {
        rval = Send_File(URI, Socket);  // 发送数据html文件或者其他
    }

    if(rval == OK){
        printf("The process is successfully finished!\n");
    }

    return OK;
}

// 查看传入的请求类型  GET是向服务器获取数据,POST是向服务器提交数据
const char* Judge_Method(char* method, int Socket){

    if(strcmp(method, "GET") == 0){
        return "GET";
    }else if(strcmp(method, "POST") == 0){
        return "POST";
    }else{
        Error_Request_Method(Socket);
        return ERROR;
    }

}

int Judge_URI(char* URI, int Socket){

    if (Inquire_File(URI) == ERROR){
        File_not_Inquire(Socket);
        return ERROR;
    } else {
        return OK;
    }

}

// 等待数据被成功发送
int Send_Ifon(int Socket, const char* sendbuf, int Length){

    int sendtotal = 0, bufleft, rval = 0;

    bufleft = Length;
    while(sendtotal < Length){
        rval = send(Socket, sendbuf + sendtotal, bufleft, 0);
        if(rval < 0){
            break;
        }
        sendtotal += rval;
        bufleft -= rval;
    }

    return rval < 0 ? ERROR : OK;

}

int Error_Request_Method(int Socket){

    const char* Method_err_line = "HTTP/1.1 501 Not Implemented\r\n";
    const char* cur_time = "";
    const char* Method_err_type = "Content-type: text/plain\r\n";
    const char* File_err_length = "Content-Length: 41\r\n";
    const char* Method_err_end = "\r\n";
    const char* Method_err_info = "The request method is not yet completed!\n";

    printf("The request method from client's request message is not yet completed!\n");

    if(Send_Ifon(Socket, Method_err_line, strlen(Method_err_line)) == ERROR){
        printf("Sending method_error_line failed!\n");
        return ERROR;
    }

    if(Send_Ifon(Socket, Server_name, strlen(Server_name)) == ERROR){
        printf("Sending Server_name failed!\n");
        return ERROR;
    }

    cur_time = Get_Data(cur_time);
    Send_Ifon(Socket, "Date: ", 6);
    if(Send_Ifon(Socket, cur_time, strlen(cur_time)) == ERROR){
        printf("Sending cur_time error!\n");
        return ERROR;
    }

    if(Send_Ifon(Socket, Method_err_type, strlen(Method_err_type)) == ERROR){
        printf("Sending method_error_type failed!\n");
        return ERROR;
    }

    if(Send_Ifon(Socket, Method_err_end, strlen(Method_err_end)) == ERROR){
        printf("Sending method_error_end failed!\n");
        return ERROR;
    }

    if(Send_Ifon(Socket, Method_err_info, strlen(Method_err_info)) == ERROR){
        printf("Sending method_error_info failed!\n");
        return ERROR;
    }

    return OK;

}

int Inquire_File(char* URI){

    char cwd[BUF_SIZE];
    if(getcwd(cwd, sizeof(cwd)) == NULL){
        perror("getcwd() error");
        return ERROR;
    }

    char abs_path[BUF_SIZE];
    snprintf(abs_path, sizeof(abs_path), "%s%s", cwd, URI);

    struct stat File_info;
    if(stat(abs_path, &File_info) == -1){
        return ERROR;
    }else{
        return OK;
    }

}

int File_not_Inquire(int Socket) {

        const char* File_err_line = "HTTP/1.1 404 Not Found\r\n";
        const char* cur_time = "";
        const char* File_err_type = "Content-type: text/html\r\n";
        const char* File_err_end = "\r\n";

        FILE* file;
        struct stat file_stat;
        char sendbuf[BUF_SIZE];
        int send_length;

        char cwd[BUF_SIZE];
        if (getcwd(cwd, sizeof(cwd)) == NULL){
            perror("getcwd() error");
            return ERROR;
        }

        char abs_path[BUF_SIZE];
        snprintf(abs_path, sizeof(abs_path), "%s/404.html", cwd);

        file = fopen(abs_path, "rb");
        if(file != NULL){
            fstat(fileno(file), &file_stat);

            if(Send_Ifon(Socket, File_err_line, strlen(File_err_line)) == ERROR){
                printf("Sending file_error_line error!\n");
                fclose(file);
                return ERROR;
            }

            if(Send_Ifon(Socket, Server_name, strlen(Server_name)) == ERROR){
                printf("Sending Server_name failed!\n");
                fclose(file);
                return ERROR;
            }

            cur_time = Get_Data(cur_time);
            Send_Ifon(Socket, "Date: ", 6);
            if(Send_Ifon(Socket, cur_time, strlen(cur_time)) == ERROR){
                printf("Sending cur_time error!\n");
                fclose(file);
                return ERROR;
            }

            if(Send_Ifon(Socket, File_err_type, strlen(File_err_type)) == ERROR){
                printf("Sending file_error_type error!\n");
                fclose(file);
                return ERROR;
            }

            char content_length[BUF_SIZE];
            snprintf(content_length, sizeof(content_length), "Content-Length: %ld\r\n", file_stat.st_size);
            if(Send_Ifon(Socket, content_length, strlen(content_length)) == ERROR){
                printf("Sending file_error_length error!\n");
                fclose(file);
                return ERROR;
            }
            if(Send_Ifon(Socket, File_err_end, strlen(File_err_end)) == ERROR){
                    printf("Sending file_error_end error!\n");
                    fclose(file);
                    return ERROR;
                }

            while((send_length = fread(sendbuf, 1, BUF_SIZE, file)) > 0){
                if (Send_Ifon(Socket, sendbuf, send_length) == ERROR) {
                    printf("Sending 404.html content error!\n");
                    break;
                }
            }

            fclose(file);
        }else{
            printf("Failed to open 404.html!\n");
            return ERROR;
        }

    return OK;

}

// 构建发送格式发送文件给浏览器函数

/**
 * const char* response = 
    "HTTP/1.1 200 OK\r\n"  // 状态行
    "Date: Wed, 08 Jan 2025 12:00:00 GMT\r\n"  // 日期时间
    "Content-Type: text/html\r\n"  // 内容类型
    "Content-Length: 1234\r\n"  // 内容长度
    "\r\n"  // 响应头结束
    "<html>...</html>";  // 响应体(文件内容)
 */


int Send_File(char* URI, int Socket) {

    char cwd[BUF_SIZE];
    if(getcwd(cwd, sizeof(cwd)) == NULL){
        perror("getcwd() error");
        return ERROR;
    }

    char abs_path[BUF_SIZE];
    snprintf(abs_path, sizeof(abs_path), "%s%s", cwd, URI);  // 路径

    const char* File_ok_line = "HTTP/1.1 200 OK\r\n";   // 成功响应
    const char* cur_time = "";
    const char* File_ok_type = "";
    const char* File_ok_length = "Content-Length: ";
    const char* File_ok_end = "\r\n";

    FILE* file;
    struct stat file_stat;
    char Length[BUF_SIZE];
    char sendbuf[BUF_SIZE];
    int send_length;

    if(Judge_File_Type(abs_path, File_ok_type) == ERROR){
        printf("The request file's type from client's request message is error!\n");
        return ERROR;
    }

    file = fopen(abs_path, "rb");
    if(file != NULL){
        fstat(fileno(file), &file_stat); // 获取文件储存信息
        snprintf(Length, sizeof(Length), "%ld", file_stat.st_size);

        if(Send_Ifon(Socket, File_ok_line, strlen(File_ok_line)) == ERROR){     // 发送接收信息成功头部
            printf("Sending file_ok_line error!\n");
            return ERROR;
        }

        if(Send_Ifon(Socket, Server_name, strlen(Server_name)) == ERROR){   // 发送服务器响应头
            printf("Sending Server_name failed!\n");
            return ERROR;
        }

        cur_time = Get_Data(cur_time);
        Send_Ifon(Socket, "Date: ", 6);
        if(Send_Ifon(Socket, cur_time, strlen(cur_time)) == ERROR){ // 发送时间日期信息
            printf("Sending cur_time error!\n");
            return ERROR;
        }

        File_ok_type = Judge_File_Type(abs_path, File_ok_type);
        if(Send_Ifon(Socket, File_ok_type, strlen(File_ok_type)) == ERROR){ // 发送内容类型
            printf("Sending file_ok_type error!\n");
            return ERROR;
        }

        if(Send_Ifon(Socket, File_ok_length, strlen(File_ok_length)) != ERROR){ // 发送内容长度
            if(Send_Ifon(Socket, Length, strlen(Length)) != ERROR){
                if(Send_Ifon(Socket, "\n", 1) == ERROR){
                    printf("Sending file_ok_length error!\n");
                    return ERROR;
                }
            }
        }

        if(Send_Ifon(Socket, File_ok_end, strlen(File_ok_end)) == ERROR){   // 响应结束
            printf("Sending file_ok_end error!\n");
            return ERROR;
        }
        // 发送响应体
        while(file_stat.st_size > 0){
            if(file_stat.st_size < 1024){
                send_length = fread(sendbuf, 1, file_stat.st_size, file);
                if(Send_Ifon(Socket, sendbuf, send_length) == ERROR){
                    printf("Sending file information error!\n");
                    continue;
                }
                file_stat.st_size = 0;
            }else{
                send_length = fread(sendbuf, 1, 1024, file);
                if(Send_Ifon(Socket, sendbuf, send_length) == ERROR){
                    printf("Sending file information error!\n");
                    continue;
                }
                file_stat.st_size -= 1024;
            }
        }
    }else{
        printf("The file is NULL!\n");
        return ERROR;
    }

    return OK;

}

// 确定传输的文件类型

const char* Judge_File_Type(char* URI, const char* content_type) {
    const char* suffix;

    if ((suffix = strrchr(URI, '.')) != NULL)
        suffix = suffix + 1;

    if (strcmp(suffix, "html") == 0) {
        return "Content-type: text/html\r\n";
    } else if (strcmp(suffix, "jpg") == 0) {
        return "Content-type: image/jpeg\r\n";
    } else if (strcmp(suffix, "png") == 0) {
        return "Content-type: image/png\r\n";
    } else if (strcmp(suffix, "gif") == 0) {
        return "Content-type: image/gif\r\n";
    } else if (strcmp(suffix, "txt") == 0) {
        return "Content-type: text/plain\r\n";
    } else if (strcmp(suffix, "xml") == 0) {
        return "Content-type: text/xml\r\n";
    } else if (strcmp(suffix, "rtf") == 0) {
        return "Content-type: text/rtf\r\n";
    } else if (strcmp(suffix, "js") == 0) {
        return "Content-type: application/javascript\r\n";
    } else if (strcmp(suffix, "css") == 0) {
        return "Content-type: text/css\r\n";
    } else if (strstr(URI, ".mp3") != NULL) {
        return "Content-Type: audio/mpeg\r\n";
    } else {
        return ERROR;
    }
}

const char* Get_Data(const char* cur_time) {
    time_t curtime;
    time(&curtime);
    cur_time = ctime(&curtime);

    return cur_time;
}

const char* Post_Value(char* message) {
    const char* suffix;

    if ((suffix = strrchr(message, '\n')) != NULL)
        suffix = suffix + 1;
    printf("\n\n$$$$-1 Post Value: %s\n\n", suffix);

    return suffix;
}

int Logo() {

    printf("/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\n");
    printf("|  程序启动了!\n");
    printf(" \n");
    printf("  ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄\n");
    printf("  ∧_∧\n");
    printf(" ( ∧_∧) \n");
    printf(" (  つつヾ\n");
    printf("  | | |\n");
    printf(" (__)_)\n");
    printf("\n");
    printf("___________________________________________________________\n\n");
    return OK;
}

int main(int argc, char* argv[]) {
    // 初始化套接字
    int port = SERVER_PORT;

    if (argc == 2) {
        port = atoi(argv[1]);
    }

    int ServerSock, MessageSock;
    struct sockaddr_in ClientAddr;
    int rval, Length;
    char revbuf[BUF_SIZE];

    Logo();
    printf("Web Server is starting on port %d...\n\n", port);
    ServerSock = Server_Socket_Init(port);
    printf("\n-----------------------------------------------------------\n");

    // 监听和处理请求

    rval = listen(ServerSock, BACKLOG); // 监听
    if (rval < 0) {
        perror("Failed to listen socket!");
        exit(1);
    }
    printf("Listening the socket on port %d...\n", port);
    Length = sizeof(ClientAddr);
    

    while (OK) {

        MessageSock = accept(ServerSock, (struct sockaddr*)&ClientAddr, &Length);   // 创建与客户端通信的套接字
        if (MessageSock < 0) {
            perror("Failed to accept connection from client!");
            exit(1);
        }
        printf("Succeed to accept connection from [%s:%d] !\n\n", inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port));

        memset(revbuf, 0, BUF_SIZE);
        rval = recv(MessageSock, revbuf, BUF_SIZE, 0);
        if (rval <= 0) {
            printf("Failed to receive request message from client!\n");
        } else {
            printf("$$$$$$ recvbuf: %s\n", revbuf);
            rval = Handle_Request_Message(revbuf, MessageSock);
        }

        printf("\n-----------------------------------------------------------\n");
        close(MessageSock);
    }

     
    close(ServerSock);

    return OK;
}

效果:

在这里插入图片描述

浏览器通过访问http://localhost:8080/与后端建立连接

后端主要为浏览器提供服务操作,而前端主要接收后端传递的数据,做渲染显示

前端的每次请求,后端都会创建一个与前端通信的套接字,用以回复消息

前端发送给后端的消息,后端发送给前端的消息都是有格式的,所以后端接收消息要做拆解解读,后端发送消息的时候要做封装

后端根据前端需求会发送很多类型的数据,如html数据用于给前端做跳转做渲染,音乐二进制文件或者图片文件用于给前端做声音响应或显示

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AnaConda下载PyTorch慢的解决办法

使用Conda下载比较慢&#xff0c;改为pip下载 复制下载链接到迅雷下载 激活虚拟环境&#xff0c;安装whl&#xff0c;即可安装成功 pip install D:\openai.wiki\ChatGLM2-6B\torch-2.4.1cu121-cp38-cp38-win_amd64.whl

Sentinel服务保护 + Seata分布式事务

服务保护 【雪崩问题】微服务调用链路中某个服务&#xff0c;引起整个链路中所有微服务都不可用。 【原因】&#xff1a; 微服务相互调用&#xff0c;服务提供者出现故障。服务调用这没有做好异常处理&#xff0c;导致自身故障。调用链中所有服务级联失败&#xff0c;导致整个…

六、Angular 发送请求/ HttpClient 模块

一、应用 HttpClient 模块 angular/common/http 中的 HttpClient 类基于浏览器提供的 XMLHttpRequest 接口。要想使用 HtpClient 模块&#xff0c;就要先导入 Anqular 的 HttpClientModule。大多数 Web 应用程序都会在根模块 AppModule 中导入它。 编辑 src/app/app.module.ts…

CompletableFuture // todo

相比较所有代码都在主线程执行&#xff0c;使用Future的好处&#xff1a;利用服务器多核、并发的优势。 不足&#xff1a; 开启没有返回值的异步线程&#xff1a; 1、runAsync 使用lambda表达式&#xff1a; 开启有返回值的异步线程&#xff1a; 1、supplyAsync 异步任务中的…

css面试常考布局(圣杯布局、双飞翼布局、三栏布局、两栏布局、三角形)

两栏布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> &…

arcgisPro加载天地图(CGCS2000)影像

1、注册天地图账号&#xff1b; 2、申请key&#xff1b; 3、添加WMTS服务器。 这里已经办好了前两步&#xff0c;下面详细介绍最后一步。 添加WMTS服务器。 在天地图网站&#xff0c;找到如下页面&#xff0c; 复制网址&#xff0c;如&#xff1a;http://t0.tianditu.gov.cn…

继承(7)

大家好&#xff0c;今天我们继续来学习一下继承的知识&#xff0c;这方面需要大家勤动脑才能理解&#xff0c;那么我们来看。 1.9 protected关键字 在类和对象章节中&#xff0c;为了实现封装特性,java中引入访向限定符,主要限定:类或者类中成员能否在类外和其他包中被访问. …

ModuleNotFoundError: No module named ‘podm.metrics‘报错等解决方法

ModuleNotFoundError: No module named podm.metrics’报错等解决方法 podm.metrics 在运行时报错&#xff1a; ModuleNotFoundError: No module named ‘podm.metrics’ 安装了podm后还是报错 解决方法&#xff1a; 查看安装位置 查看podm的安装位置&#xff0c;并打开到该…

HDFS异构存储和存储策略

一、HDFS异构存储类型 1.1 冷、热、温、冻数据 通常&#xff0c;公司或者组织总是有相当多的历史数据占用昂贵的存储空间。典型的数据使用模式是新传入的数据被应用程序大量使用&#xff0c;从而该数据被标记为"热"数据。随着时间的推移&#xff0c;存储的数据每周…

sklearn-逻辑回归-制作评分卡

目录 数据集处理 分箱 分多少个箱子合适 分箱要达成什么样的效果 对一个特征进行分箱的步骤 分箱的实现 封装计算 WOE 值和 IV值函数 画IV曲线&#xff0c;判断最佳分箱数量 结论 pd.qcut 执行报错 功能函数封装 判断分箱个数 在银行借贷场景中&#xff0c;评分卡是…

中学综合素质笔记3

第一章职业理念 第三节 教师观 考情提示&#xff1a; 单选题材料分析题 学习要求&#xff1a; 理解、 识记、 运用 &#xff08;一&#xff09;教师职业角色的转变&#xff08;单选材料分析&#xff09; 从教师与学生的关系看——对学生 新课程要求教师应该是学生学习的引…

【Linux】设备驱动中的ioctl详解

在Linux设备驱动开发中&#xff0c;ioctl&#xff08;输入输出控制&#xff09;是一个非常重要的接口&#xff0c;用于用户空间应用程序与内核空间设备驱动之间进行通信。通过ioctl&#xff0c;应用程序可以发送命令给设备驱动&#xff0c;控制设备的行为或获取设备的状态信息。…

linux上使用cmake编译的方法

一、hello 例程仅基于一个cpp文件 C文件或工程进行编译时可以使用g指令&#xff08;需要对每一个程序和源文件分别使用g指令编译&#xff09;&#xff0c;当程序变大时&#xff0c;一个工程文件往往会包含很文件夹和源文件&#xff0c;这时我们需要的编译指令将越来越长&#…

(vue)el-table-column type=“selection“表格选框怎么根据条件添加禁选

(vue)el-table-column type"selection"表格选框怎么根据条件添加禁选 html <el-table:data"tableData"style"width: 100%"><el-table-columntype"selection"width"55":selectable"checkSelectable">…

linux nginx 安装后,发现SSL模块未安装,如何处理?

&#x1f468;‍⚕ 主页&#xff1a; gis分享者 &#x1f468;‍⚕ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕ 收录于专栏&#xff1a;运维工程师 文章目录 前言SSL模块安装 前言 nginx 安装后&#xff0c;发现SSL模块未安装&…

kubeneters-循序渐进Cilium网络(二)

文章目录 概要IP 地址配置接口配置解析结论 概要 接续前一章节&#xff0c;我们还是以这张图继续深入Cilium网络世界 IP 地址配置 通过检查 Kubernetes 集群的当前环境&#xff0c;可以获取实际的 IP 地址和配置信息。这些信息将被补充到之前的网络示意图中&#xff0c;以使…

虚拟机使用MQ及介绍

mq官网&#xff1a;https://www.rabbitmq.com 一、虚拟机与 MQ 的结合优势 隔离与安全&#xff1a;虚拟机为 MQ 的运行提供了一个独立的环境&#xff0c;与宿主机以及其他虚拟机相互隔离。这意味着即使 MQ 所在的虚拟机出现故障或遭受安全威胁&#xff0c;也不会直接影响到宿主…

比亚迪夏直插家用MPV腹地,“迪王”开启全面销冠新征程

文/王俣祺 导语&#xff1a;比亚迪前脚刚收获2024年的全面成功&#xff0c;后脚立刻就开始布局2025年的产品矩阵了。比亚迪夏的横空出世&#xff0c;看来家用MPV市场也要感受“迪王”的恐怖如斯了。 家用MPV市场的“意外之喜” 1月8日&#xff0c;比亚迪夏终于在万众瞩目之下…

c++入门之 命名空间与输入输出

1、命名空间 1.1使用命名空间的原因 先看一个例子&#xff1a; #include <iostream>int round 0;int main() {printf("%d", round);return 0; }请问&#xff0c;这个程序能跑起来吗&#xff1f; 答案是否定的 原因是&#xff0c;当我们想创建一个全局变量 …

php 使用simplexml_load_string转换xml数据格式失败

本文介绍如何使用php函数解析xml数据为数组。 <?php$a <xml><ToUserName><![CDATA[ww8b77afac71336111]]></ToUserName><FromUserName><![CDATA[sys]]></FromUserName><CreateTime>1736328669</CreateTime><Ms…