小型web服务器

#pragma once                                                                    
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/sendfile.h>
#include<fcntl.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<pthread.h>
#include<errno.h>
#define _DET_PAGE_ index.html
#define _SIZE_ 1024
static void printLog(const char* const str,const char* const fun,int line);
void usage(const char*  const  proc);
int startup(char* ip,int port);
int get_line(int sock,char* buf,int size);
void clear_head(int sock);
void echo_html(int sock,char* path,ssize_t size);
void accept_request(int sock);
void* handle_client(void* arg);
 
#include"http.h"                                                                
static void printLog(const char* const str,const char* const fun,int line)
{
    printf("%s:%s:%d\n",str,fun,line);
}
void usage(const char*  const  proc)
{
    assert(proc);
    printLog(proc,__FUNCTION__,__LINE__);
}
int startup(char* ip,int port)
{
    int sock=socket(AF_INET,SOCK_STREAM,0);
    if(sock<0)
    {
        printLog(strerror(errno),__FUNCTION__,__LINE__);
        exit(1);
    }
    int opt=1;
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    struct sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_port=htons(port);
    local.sin_addr.s_addr=inet_addr(ip);
    if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
    {
        printLog(strerror(errno),__FUNCTION__,__LINE__);
        exit(1);
    }
    if(listen(sock,5)<0)
    {
        printLog(strerror(errno),__FUNCTION__,__LINE__);
        exit(1);
    }
    return sock;
}
int get_line(int sock,char* buf,int size)
{
    assert(buf);
    int i=0;
    ssize_t _s=-1;
    char ch=‘\0‘;
    while(i<size-1)
    {
        _s=recv(sock,&ch,1,0);
        if(_s>0)                             
        {
            if(ch==‘\r‘)
            {
                if(_s=recv(sock,&ch,1,MSG_PEEK))
                {
                    if(_s>0&&ch==‘\n‘)
                        recv(sock,&ch,1,0);
                }
            }
            buf[i++]=ch;
        }
        else
        {
            break;
        }
    }
    buf[i]=‘\0‘;
    return i;
}
void clear_head(int sock)
{
    char buf[_SIZE_];
    buf[0]=‘\0‘;                
    ssize_t _s=-1;
    while(_s>0&&strcmp(buf,"\n")!=0)
    {
        get_line(sock,buf,sizeof(buf));
    }
}
void echo_html(int sock,char* path,ssize_t size)
{
    int fd=open(path,O_RDONLY);
    if(fd<0)
    {
        printLog(strerror(errno),__FUNCTION__,__LINE__);
        exit(1);
    }
    char* status_line="HTTP/1.1 200 ok/r/n/r/n";
    send(sock,status_line,strlen(status_line));
    if(sendfile(sock,fd,NULL,size)<0)
    {
        close(fd);
        return;
    }
    close(fd);
}                                    
void accept_request(int sock)
{
    char buf[_SIZE_];
#ifdef _DEBUG1_
    int ret=-1;
    int i=0,j=0;
    char method[_SIZE_/2];
    char url[_SIZE_];
    char path[_SIZE_];
    memset(method,‘\0‘,sizeof(method));
    memset(buf,‘\0‘,sizeof(buf));
    memset(path,‘\0‘,sizeof(path));
    memset(url,‘\0‘,sizeof(url));

    //while(ret=get_line(sock,buf,sizeof(buf)>0))
    //{
    //  if(ret==0)
    //  {
    //      printLog(strerror(errno),__FUNCTION__,__LINE__);
    //      break;
    //  }
    //  printf("%s",buf);
    //}                            
    if(get_line(sock,buf,sizeof(buf))==0)
    {
        printLog("errno",__FUNCTION__,__LINE__);
        return;
    }
    i=j=0;
    while(!isspace(buf[i])&&i<sizeof(buf)&&j<sizeof(method)-1)
    {
        method[j++]=buf[i++];//get method
    }
    method[j]=‘\0‘;
    
    j=0;
    while(isspace(buf[i]))
    {
        ++i;
    }
    while(!isspace(buf[i])&&i<sizeof(buf)&&j<sizeof(url)-1)
    {
        url[j++]=buf[i++];
    }
    int cgi=0;
    if(strncasecmp(method,"POST")!=0&&strncasecmp(method,"GET")!=0)  
    {
        printLog("errno",__FUNCTION__,__LINE__);
        return;
    }
    if(strncasecmp(method,"POST"))
    {
        cgi=1;
    }
    if(strncasecmp(method,"GET"))
    {
        char* query_string=url;
        while(*query_string!=‘\0‘&&*query_string!=‘?‘)
        {
            if(*query_string==‘?‘)
            {
                *query_string=‘\0‘;
                cgi=1;
            }
            ++query_string;
        }
        sprintf(path,"ntdos%s",url);//sprintf
        if(path[strlen(path)-1]==‘/‘)
        {                                     
            strcat(path,_DET_PAGE_);
        }

        struct stat st;
        if(stat(path,&st)<0)//not exist
        {
            printLog("errno",__FUNCTION__,__LINE__);
            return;
        }
        else if(S_ISDIR(st.st_mode))//dir
        {
            strcpy(path,"htdocs/");
            strcat(path,_DEF_PAGE_);
        }
        else if((st.st_mode&S_IXUSR)||(st.st_mode&S_IXGPR)||(st.st_mode&S_IXOTH))
        {
            cgi=1;
        }
        if(cgi)
        {
            execute_cgi(sock,path,method,query_string);
        }                                                                                          
        else
        {
            clear_head(sock);
            echo_html(sock,path,st.st_size);
        }
    }

#endif 
    close(sock);
}
void* handle_client(void* arg)
{
    int sock=(int)arg;
    accept_request(sock);
    return NULL;
}                          
//main.c 
#include"http.h"                                                                                   
int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        usage(argv[0]);
        return 1;
    }
    char* ip=argv[1];
    int port=atoi(argv[2]);
    int listen_sock=startup(ip,port);
    struct sockaddr_in client;
    socklen_t len=sizeof(client);
    fflush(stdout);
    while(1)
    {
        int new_sock=accept(listen_sock,(struct sockaddr*)&client,&len);
        if(new_sock<0)
        {
            printf("no client");
            fflush(stdout);
            continue;
        }
        pthread_t id;
        pthread_create(&id,NULL,handle_client,(void*)new_sock);
        pthread_detach(id);//set detach return val:0/errno      
    }
    return 0;
}                                                                              					
时间: 2025-01-12 04:26:09

小型web服务器的相关文章

Tiny server:小型Web服务器

一.背景 csapp的网络编程粗略的介绍了关于网络编程的一些知识,在最后的一节主要就实现了一个小型的Webserver.这个server名叫Tiny,它是一个小型的可是功能齐全的Webserver.在短短300行左右的代码中,结合了很多思想,比如,进程控制,unix I/O.套接字.HTTP等,令人兴奋的是,它能够为Web浏览器提供静态和动态的内容,也就是说在浏览器中要打开的HTML之类的文件能够直接通过Tiny直接显示在窗体. 我一直想要学习网络编程,这或许就是第一个做成的东西吧,想想都让人兴

Web服务器集群搭建

前言:本文记述了搭建一个小型web服务器集群的过程,由于篇幅所限,系统.软件的安装和基本配置我这里就省略了,只记叙关键配置和脚本内容.假如各位朋友想了解各软件详细配置建议查阅官方文档. 一 需求分析: 1.整体需求:搭建一个高可用的网站服务器集群,能承受高并发请求,能抵御一般的网络攻击,任何一台服务器的退服不影响整个集群的运作,并且能对各服务器的运行情况作出实时监控. 2.详细需求分析: 根据需求,计划根据以下拓扑搭建运行环境: 二 详细功能描述: 1.前端服务器采用nginx实现反向代理和负载

利用node.js搭建简单web服务器的方法教程

前言 使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块.路径解析模块.以及301重定向问题,下面我们就简单讲一下如何来搭建一个简单的Web服务器. 早先不使用web服务器的情况下想要在浏览器端访问本地资源,可以利用firefox浏览器,其可以自己启动一个小型web服务器. 为了让刚接触node的人也能大体看懂,本文的代码我将尽量简化. 准备 首先,

常用的Web服务器

常用的Web服务器有IIS.Apache.Tomcat.Jboss.Resin.Weblogic.WebSpher IISIIS服务是Windows产品自带的一种免费的Web服务器,安装配置简单,主要解析的是ASP程序代码,对于小型的.利用ASP编程的项目,可以采用其作为Web服务器.一般可以跟Apache整合起来使用.这种服务在配置过程中需要注意权限的问题.Apache世界排名第一.免费开源的Web服务器软件,可以安装运行在绝大多数的计算机平台上,支持大多数语言开发的B/S结构软件.一般情况下

第五章、web服务器

一.web服务器 Web服务器就是整个万维网的骨干,广义上来说Web服务器既可以用来表示Web服务器的软件,也可以用来表示提供Web页面的特定设备和计算机.我们在网络上获取的所以资源,都需要有服务器来保存和提供.另外需要说明的是本篇中对于Web服务器的配置说明是基于Apache Web服务器的. 1 Web服务器的类型 Web 服务器有着不同的风格.形状和尺寸.有普通的 10 行 Perl 脚本的 Web 服务器.50MB 的安全商用引擎以及极小的卡上服务器.但不管功能有何差异,所有的 Web

小型公司访问web服务器案例

今天主要给大家带来一个小型公司的网络搭建,保证每一台计算机都可以访问www.ntd1711.com. 实验名称:小型公司网络的搭建 实验拓扑:实验目的:确保每个终端可以访问www.ntd1711.com(192.168.30.88)地址规划: 设备 IP地址及子网掩码 所属vlan 网关 PC1 192.168.10.1/24 VLAN10 192.168.10.254 PC2 192.168.20.2/24 VLAN20 192.168.20.254 PC3 192.168.10.3/24 V

[转]三大WEB服务器对比分析(apache ,lighttpd,nginx)

原博文地址:http://www.blogjava.net/daniel-tu/archive/2008/12/29/248883.html 一.软件介绍(apache  lighttpd  nginx) 1. lighttpd Lighttpd是一个具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点.lighttpd是众多OpenSource轻量级的web server中较为优秀的一个.支持FastCGI, CGI, Auth, 输出压缩(output compress), U

Java中常见的5种WEB服务器介绍

这篇文章主要介绍了Java中常见的5种WEB服务器介绍,它们分别是Tomcat.Resin.JBoss.WebSphere.WebLogic,需要的朋友可以参考下 Web服务器是运行及发布Web应用的容器,只有将开发的Web项目放置到该容器中,才能使网络中的所有用户通过浏览器进行访问.开发Java Web应用所采用的服务器主要是与JSP/Servlet兼容的Web服务器,比较常用的有Tomcat.Resin.JBoss.WebSphere 和 WebLogic 等,下面将分别进行介绍. Tomc

python web编程-CGI帮助web服务器处理客户端编程

这几篇博客均来自python核心编程 如果你有任何疑问,欢迎联系我或者仔细查看这本书的地20章 另外推荐下这本书,希望对学习python的同学有所帮助 概念预热 eb客户端通过url请求web服务器里的静态页面,但是要怎么做到洞察不同用户同的输入?比如说表单提交等来产生不同的返回结果呢 一个简单的思路是web服务器把这些请求提交给另外一个程序,它接受用户输入然后处理,根据输入生成一个静态的html文件交给web服务器 复杂上面这样的流程程序就是CGI,是单独出来的 创建HTML 的CGI 应用程