Chinaunix首页 | 论坛 | 博客
  • 博客访问: 270706
  • 博文数量: 50
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 919
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-03 19:18
个人简介

非淡泊无以明志,非宁静无以致远

文章分类

全部博文(50)

文章存档

2018年(2)

2017年(6)

2016年(7)

2015年(10)

2014年(11)

2013年(14)

我的朋友

分类: 嵌入式

2013-07-03 19:44:46

//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 Moved

Object Moved

This 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[i] = strtok(buf, str);
    while((bak[++i] = strtok(NULL, str)));
    size = i;
    return size;
}
阅读(1096) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~