zoukankan      html  css  js  c++  java
  • 简易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;
    }
  • 相关阅读:
    PAT Advanced 1067 Sort with Swap(0, i) (25分)
    PAT Advanced 1048 Find Coins (25分)
    PAT Advanced 1060 Are They Equal (25分)
    PAT Advanced 1088 Rational Arithmetic (20分)
    PAT Advanced 1032 Sharing (25分)
    Linux的at命令
    Sublime Text3使用指南
    IntelliJ IDEA创建第一个Groovy工程
    Sublime Text3 安装ftp插件
    Sublime Text3配置Groovy运行环境
  • 原文地址:https://www.cnblogs.com/hnrainll/p/2036725.html
Copyright © 2011-2022 走看看