WebSever簡易實現




//main.h
//====================================================================================
// The information contained herein is the exclusive property of
// Sunnnorth Technology Co. And shall not be distributed, reproduced,
// or disclosed in whole in part without prior written permission.
// (C) COPYRIGHT 2003 SUNNORTH TECHNOLOGY CO.
// ALL RIGHTS RESERVED
// The entire notice above must be reproduced on all authorized copies.
//====================================================================================

#ifndef _MAIN_H_
#define _MAIN_H_
#include stdio.h>
#include stdlib.h>
#include unistd.h>
#include string.h>
#define RECV_SZIE 1024
#define SEND_SIZE 1024
int cut_list(char *bak[], char *buf, char *str);
void deal_with(int connfd, char *buf);
#endif
//main.h
//=============================================================
// 語法格式: int main(int argc, char *argv[])
// 實現功能: 主函數,建立一個webServer
// 入口參數: argc, argv
// 出口參數: 0
//=============================================================
#include "main.h"
#include sys/socket.h>
#include netinet/in.h>
#include arpa/inet.h>
#include sys/types.h>
int main(int argc, char *argv[])
{
    char recvbuf[RECV_SZIE];
    int sockfd;
    struct sockaddr_in servAddr;
    unsigned short port = 80;
    pid_t pid;
    if(argc > 1)
    {
        port = atoi(argv[1]);
    }
    printf("webserver Started at port %d\n", port);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd  0)
    {
        perror("Invalid socket!");
        exit(1);
    }
    bzero(&servAddr, sizeof(servAddr));        //initialize server
    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)
    {
        close(sockfd);
        perror("binding err!");
        exit(1);
    }
    if(listen(sockfd, 1) != 0)
    {
        close(sockfd);
        perror("listen err!");
        exit(1);
    }
   
    char cliIP[INET_ADDRSTRLEN];
    size_t recvLen;
    struct sockaddr_in cliAddr;
    size_t cliAddrLen = sizeof(cliAddr);
    while(1)
    {
        int connfd = accept(sockfd, (struct sockaddr *)&cliAddr, &cliAddrLen);
        if(connfd  0)
        {
            close(sockfd);
            perror("accept err!");
            exit(1);
        }
        inet_ntop(AF_INET, &cliAddr.sin_addr.s_addr, cliIP, INET_ADDRSTRLEN);
        printf("client ip = %s\n", cliIP);
        
        if((pid = fork())  0)
        {
            perror("fork err!");
            exit(1);
        }
        else if(pid == 0)
        {
            close(sockfd);
            if((recvLen = read(connfd, recvbuf, RECV_SZIE)) > 0)
            {
                printf("%s\n", recvbuf);
                deal_with(connfd, recvbuf);
                memset(recvbuf, 0, RECV_SZIE);
            }
            close(connfd);
            exit(1);
        }
        else
        {
            close(connfd);
            printf("client closed!\n");
        }
    }
    close(sockfd);
    return 0;
}
//webserver.c
//=============================================================
// 語法格式: void deal_with(int connfd, char *buf)
// 實現功能: 處理客戶端的請求
// 入口參數: conndf,buf
// 出口參數: 無
//=============================================================
#include "main.h"
#include fcntl.h>
#include sys/stat.h>
void deal_with(int connfd, char *buf)
{
    char *resp_head =    "HTTP/1.1 200 OK\r\n"                \
                        "Content-Type: text/html\r\n"        \
                        "Content-Length:%ld\r\n"            \
                        "\r\n";
    char *not_found =    "HTTP/1.1 404 Not Found\r\n"        \
                        "Content-Type: text/html\r\n"        \
                        "Content-Length: 40\r\n"            \
                        "\r\n"                                \
                        "File not found";
    char *bad_request = "HTTP/1.1 400 Bad Request\r\n"        \
                        "Content-Type: text/html\r\n"        \
                        "Content-Length: 39\r\n"            \
                        "\r\n"                                \
                        "Bad Request (Invalid Hostname)";
/*    char *moved_permanently =
                        "HTTP/1.1 301 Moved Permanently\r\n"\
                        "Content-Length: 147\r\n"            \
                        "Content-Type: text/html\r\n"        \
                        "Location: %s\r\n"                    \
                        "\r\n"                                \
                        "Document MovedObject MovedThis document may be found here";
*/
    char tmp_buf[SEND_SIZE] = {""};
    char *tmp_bak[10];
    char *first_line[5];
    int fd;
    FILE *fp;
    struct stat file_buf;
    int file_len = 0;
    fp = fdopen(connfd, "w+");        //
    cut_list(tmp_bak, buf, "\r\n");
    cut_list(first_line, tmp_bak[0], " ");
    if((first_line[0] != NULL) && (strcmp(first_line[0], "GET") == 0))
    {
        if(first_line[1] != NULL)
        {
            if(strcmp(first_line[1], "/") == 0)
            {
                strcat(first_line[1], "bai.htm");
            }   
            
            first_line[1] = ++first_line[1];
               
            if((fd = open(first_line[1], O_RDONLY)) == -1)
            {
                write(connfd, not_found, strlen(not_found));
                perror("open index.html err!");
                return ;
            }
            stat(first_line[1], &file_buf);
            file_len = file_buf.st_size;
            fprintf(fp, resp_head, file_len);
            fflush(fp);
            int len;
            while((len = read(fd, tmp_buf, SEND_SIZE)) > 0)
            {
                write(connfd, tmp_buf, len);
                memset(tmp_buf, 0, SEND_SIZE);
            }
            close(fd);
        }
        else
        {
            write(connfd, bad_request, strlen(bad_request));
        }
    }
   return ;
}
/*************************************************************
*自己封裝的字符串切割函數
*功 能:切割字符串
*************************************************************/
int cut_list(char *bak[], char *buf, char *str)
{
    int i = 0;
    int size = 0;
   
    bak

= strtok(buf, str);
    while((bak[++i] = strtok(NULL, str)));
    size = i;
    return size;
}


注:以上內容整理自網絡



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章