• 简易HTTP 服务器


    //=============================================================
    // 文件名称:web.c
    // 功能描述:HTTP Server
    // 维护记录:2011-05-04 V1.0
    // 维护成员: wenhao
    //=============================================================
    #include <stdio.h>
    #include
    <stdlib.h>
    #include
    <string.h> // bzero
    #include <unistd.h>
    #include
    <sys/socket.h>
    #include
    <netinet/in.h>
    #include
    <arpa/inet.h> // inet_ntop
    #include <pthread.h>
    #include
    <sys/stat.h>
    #include
    <sys/types.h>
    #include
    <fcntl.h>


    //=============================================================
    // 语法格式: void main(void)
    // 实现功能: 主函数,建立一个HTTP Server
    // 入口参数: 无
    // 出口参数: 无
    //=============================================================
    int main(int argc, char *argv[])
    {
    int sockfd; // 套接字
    pid_t pid; //进程ID
    struct sockaddr_in servAddr; // 服务器地址结构体
    struct sockaddr_in cliAddr; // 用于保存客户端地址
    char cliIP[INET_ADDRSTRLEN]; // 用于保存客户端IP地址
    unsigned short port = 80; // 监听端口
    char head[]="HTTP/1.1 200 OK\r\n"\
    "Content-Type: text/html\r\n"\
    "\r\n";
    char err[]="HTTP/1.1 404 Not Found\r\n"\
    "Content-Type: text/html\r\n" \
    "\r\n"
    "<HTML><BODY>File not found</BODY></HTML>";

    size_t cliAddrLen
    = sizeof(cliAddr); //计算客户端的地址大小

    if(argc > 1) // 由参数接收端口
    {
    port
    = atoi(argv[1]);
    }
    printf(
    "TCP Server Started at port %d!\n", port);
    sockfd
    = socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字
    if(sockfd < 0)
    {
    perror(
    "Invalid socket");
    exit(
    1);
    }
    memset(
    &servAddr,0,sizeof(servAddr));// 初始化服务器地址
    servAddr.sin_family = AF_INET;
    servAddr.sin_port
    = htons(port);
    servAddr.sin_addr.s_addr
    = htonl(INADDR_ANY);
    printf(
    "Binding server to port %d\n", port);
    if(bind(sockfd, (struct sockaddr*)&servAddr, sizeof(struct sockaddr)) != 0) //bind绑定套接字
    {
    close(sockfd);
    perror(
    "binding err!");
    exit(
    1);
    }
    if(listen(sockfd, 1) != 0)//listen监听套接字
    {
    close(sockfd);
    perror(
    "listen err!");
    exit(
    1);
    }
    printf(
    "waiting client...\n");

    while(1)
    {
    int connfd = accept(sockfd, (struct sockaddr*)&cliAddr, &cliAddrLen);//等待服务器访问
    printf("the connfd = *%d*\n",connfd);
    inet_ntop(AF_INET,
    &cliAddr.sin_addr.s_addr, cliIP, INET_ADDRSTRLEN);
    printf(
    "client ip = %s\n", cliIP);
    pid
    = fork(); //创建进程
    if(pid == 0)
    {
    close(sockfd);
    //子进程中关闭主套接字
    char recvbuf[1024]=""; // 接收缓冲区
    char filename[100];
    int openfd;
    char filebuf[1024];
    read(connfd,recvbuf,
    1024);//从套接字中读取浏览器发送过来的数据.
    sscanf(recvbuf,"GET /%[^ ]",filename); //获取要浏览器请求的文件
    printf("filename = *%s*\n",filename);
    openfd
    = open(filename,O_RDONLY); //打开浏览器请求的文件
    if(openfd == -1)
    {
    printf(
    "the file open error!\n");
    write(connfd,err,strlen(err));
    //文件打开失败发送错误提示
    }
    else
    {
    printf(
    "the file open successful!\n");
    //注意这里是用strlen(head),而不是sizeof(),用sizeof将会导致图片打不开
    send(connfd,head,strlen(head),0); //向浏览器发送请求OK的消息
    int readflag = 0;
    //将打开的文件中的数据依次的发送给浏览器
    while((readflag=read(openfd,filebuf,sizeof(filebuf))) > 0)
    {
    printf(
    "readflag = *%d*\n",readflag);
    send(connfd,filebuf,readflag,
    0);//这里的发送数据大小为readflag,注意
    }
    }
    close(connfd);
    //本次请求结束后关闭套接字
    exit(0);//退出进程
    }
    else
    {
    close(connfd);
    //主进程要关闭子进程中用到的套接字,不然再次有请求时,会导致网页始终打不开.
    }
    }
    close(sockfd);
    return 0;
    }
  • 相关阅读:
    Git 的版本库创建和修改
    appnium框架以及源码研究
    根据图片的URL生成PDF保存到本地(前台js)
    根据图片的URL生成PDF保存到服务器上(后台C#实现)
    麻烦的控件只读
    利用Javascript生成txt文本文件
    KendoUI AngularJS Bootstrap
    给Grid动态添加列和添加样式
    linq 分组求和的一般方法
    KendoUi学习之旅 Combobox的使用
  • 原文地址:https://www.cnblogs.com/hnrainll/p/2036725.html
Copyright © 2020-2023  润新知