webserver<2>

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <errno.h>
#include "common.h"
#include "serversignal.h"
#include "server_epoll.h"

static int open_socket(struct sockaddr_in* paddr);
static int accept_client(int sockfd, struct sockaddr_in* paddr);

static int process_request(int connfd);
static volatile sig_atomic_t graceful=0;

#define HTTP_PORT 18080
#define BACK_LOG  50
#define MAX_FDS   100
#define SOCKLEN   sizeof(struct sockaddr_in)

#define err_log_exit()    do{    perror("server failed");    fprintf(stderr, "file %s line %d\n", __FILE__, __LINE__);    exit(EXIT_FAILURE);    }while(0)

#define err_msg_exit(msg)    do{    perror(msg);    fprintf(stderr, "file %s line %d\n", __FILE__, __LINE__);    exit(EXIT_FAILURE);    }while(0)
static int setnonblocking(int sockfd)
{
        if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)
        {
            return -1;
        }

        return 0;
}

int main(int argc, char *argv[])
{
            signal_init();
        int max_worker = 2;
            int child = 0;
        int epollfd = 0;
        struct sockaddr_in      saddr;
            int sockfd = 0;
        int nfds   = 0;
        int index  = 0;
        int fd = 0;
        int acceptfd = 0;
        struct epoll_event *events;

        memset(&saddr, 0, sizeof(struct sockaddr_in));        

        sockfd=open_socket(&saddr);

        if(sockfd == -1)
                err_log_exit();

            while(!graceful&&!child){
                if(max_worker>0){
                  switch(fork()){
                  case -1:
                err_log_exit();
              break;
                      case 0:
                child =1;
              break;
              default:
                printf("child creat\n");
                max_worker--;
              break;
              }
                }else{
              int status =0;
              if( -1 != wait(&status)){
                   //max_worker++;
                   fprintf(stderr, "child quit\n");
              }
                }
        }

         if(!child){
            fprintf(stderr, "before quit, kill all child\n");
            kill(0, SIGINT);
            sleep(2);
            return 0;
            }

        //child
        epollfd = server_epoll_create(MAX_FDS+1);
        if(epollfd == -1)
        err_log_exit();

        if(server_epoll_event_add(epollfd, sockfd) == -1)
        err_log_exit();

        events = (struct epoll_event*)malloc(MAX_FDS*sizeof(struct epoll_event));
        memset(events, 0, MAX_FDS*sizeof(struct epoll_event));

        /* close stdin and stdout, as they are not needed */
        /* move stdin to /dev/null */
        if (-1 != (fd = open("/dev/null", O_RDONLY))) {
            close(STDIN_FILENO);
        dup2(fd, STDIN_FILENO);
        close(fd);
        }

       /* move stdout to /dev/null */
       if (-1 != (fd = open("/dev/null", O_WRONLY))) {
         close(STDOUT_FILENO);
            dup2(fd, STDOUT_FILENO);
        close(fd);
       }

       while(child&&!graceful){
        nfds = epoll_wait(epollfd, events, MAX_FDS, 500);
        index = 0;

        while(index < nfds){

             if(events[index].data.fd == sockfd){
              acceptfd = accept_client(sockfd, &saddr);
              //waking herd
              if(acceptfd == -1){
                  perror("accept failed\n");
              }else{
                  //accept ok
                  if(server_epoll_event_add(epollfd, acceptfd) == -1)
                   err_log_exit();
              }
              }else if(events[index].data.fd == acceptfd){
              // receive data from client
              // if client close, need avoid TIME_WAIT status
              if(process_request(acceptfd) == 0){
                   fprintf(stderr, "client close, close connection and quit listen connect fd\n");
                   if(server_epoll_event_del(epollfd, acceptfd) == -1)
                        err_log_exit();
                   close(acceptfd);
              }
              }else{

              }
              index++;
        };    

        if(nfds == -1){
            if (errno == EINTR)
                continue;
            else{
                err_log_exit();
            }
        }

        };

        return 0;
}

void server_graceful_set(int g)
{
    if(g>0){
        g=1;
    }else{
        g=0;
    }
    graceful=g;
}

int server_graceful_get()
{
    return graceful;
}

static int open_socket(struct sockaddr_in* paddr)
{
    int      sockfd         = 0;
    struct  sockaddr_in     sockaddress;

    bzero(&sockaddress, sizeof(sockaddress));

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
                    err_log_exit();

    sockaddress.sin_family = AF_INET;
    sockaddress.sin_port   = htons(HTTP_PORT);    

    setnonblocking(sockfd);

    inet_pton(AF_INET, "10.174.8.163", &(sockaddress.sin_addr));

    if(bind(sockfd, (struct sockaddr*)(&sockaddress), sizeof(sockaddress)) == -1)
                    err_log_exit();

    if(listen(sockfd, BACK_LOG) == -1)
                    err_log_exit();

    *paddr = sockaddress;
    return sockfd;
}

static int accept_client(int sockfd, struct sockaddr_in* paddr)
{
    socklen_t len         = SOCKLEN;
    int       connfd    = 0;

    if(paddr != NULL)
    {
        connfd = accept(sockfd, (struct sockaddr*)(paddr), &len);
    }else
    {
        connfd = -1;
    }
    return connfd;
}

static int process_request(int connfd)
{
    char request[1000];
    int len = 0;
    bzero(request, sizeof(request));
    len = recv(connfd, request, sizeof(request), 0);
    if(len >0)
        fprintf(stderr, "%s\n", request);

    return len;
}
#include <unistd.h>
#include <string.h>
#include "server_epoll.h"

int server_epoll_event_add(int epollfd, int sockfd)
{
    struct epoll_event ep;
    memset(&ep, 0, sizeof(ep));
    ep.events = 0;
    ep.events |= EPOLLIN;
    ep.events |= EPOLLOUT;
    ep.data.fd = sockfd;    

    return epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ep);
}

int server_epoll_event_del(int epollfd, int sockfd)
{
    struct epoll_event ep;
    memset(&ep, 0, sizeof(ep));
    ep.events = 0;
    ep.events |= EPOLLIN;
    ep.events |= EPOLLOUT;
    ep.data.fd = sockfd;    

    return epoll_ctl(epollfd, EPOLL_CTL_DEL, sockfd, &ep);
}

int server_epoll_create(int size)
{
    int fd = epoll_create(size);
    return fd;
}

int server_epoll_close(int fd)
{
    return close(fd);
}

webserver<2>,布布扣,bubuko.com

时间: 2024-10-13 07:08:14

webserver<2>的相关文章

什么是WEBserver? 经常使用的WEBserver有哪些?

一.什么是WEBserver Webserver能够解析HTTP协议.当Webserver接收到一个HTTP请求,会返回一个HTTP响应,比如送回一个HTML页面.为了处理一个请求Webserver能够响应一个静态页面或图片,进行页面跳转或者把动态响应的产生托付给一些其他的程序比如CGI脚本,JSP脚本,servlets,ASP脚本,server端JavaScript,或者一些其他的server端技术.不管它们(译者注:脚本)的目的怎样,这些server端的程序通常产生一个HTML的响应来让浏览

PHP与webserver【简书看到的】

很久以前,人们造出来一个机器人,它的英文名字叫web server,中文名叫网页服务器.(为了简写,下文称web server为server) server的工作很简单,就是做内容的分发. 初期的sever功能很简单,只能处理静态请求,当客户端请求/index.html的时候,server去文件系统里面找到对应的index.html文件,然后返回给客户端,这个时期的server就像一个仓库管理员,别人要啥,他给啥. 可是这样的机器人很明显不能满足人们的需求,因为sever机器人只能处理静态请求,

【收藏】十大Webserver漏洞扫描工具

如今有很多消息令我们感到Web的危急性,因此,当前怎样构建一个安全的Web环境成为网管员和安全管理员们义不容辞的责任.可是巧妇难为无米之炊,该选择哪些安全工具呢? 扫描程序能够在帮助造我们造就安全的Web网站上助一臂之力,也就是说在黑客"黑"你之前,先測试一下自己系统中的漏洞.我们在此推荐十大Web漏洞扫描程序,供您參考. 1. Nikto 这是一个开源的Webserver扫描程序,它能够对Webserver的多种项目(包含3500个潜在的危急文件/CGI,以及超过900个server

Webserver推送技术

server推送(Server Push) 推送技术的基础思想是将浏览器主动查询信息改为server主动发送信息.server发送一批数据,浏览器显示这些数据,同一时候保证与server的连接.当server须要再次发送一批数据时,浏览器显示数据并保持连接.以后,server仍然能够发送批量数据,浏览器继续显示数据,依次类推. client拉曳(Client Pull) 在client拖曳技术中,server发送一批数据,在HTTP响应或文档头标记中插入指令,让浏览器"在5秒内再次装入这些数据&

Android中如何搭建一个WebServer

对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate 的继承映射可以理解持久化类之间的继承关系.例如:人和学生之间的关系.学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到. Hibernate支持三种继承映射策略: 使用 subclass 进行映射:将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态. 使用 joined-subclass 进行映射: 对于继承关系中的子类使用同一个表

CXF 简单创建Webserver 例子

最近在弄webserver,因为公司需要用到,来说说,webserver的常用方式吧 1.什么是webservice 1.1   什么是远程调用技术 远程调用数据定义:是系统和系统之间的调用 先说一说常用的webserver 的客户端方式吧 Webservice的四种客户端调用方式 公网服务地址: http://www.webxml.com.cn/zh_cn/index.aspx 1.1   第一种生成客户端调用方式 1.1.1  Wsimport命令介绍 l  Wsimport就是jdk提供的

2017-9-11 - Q - webServer

2 学习项目的脉络把握才是关键,对项目整体的把握,实际上方法的创建只是其次,学到老师对项目的整体把控才是最有价值的.为什么此处直接定义即可,后续不需要考虑不同情况的处理吗,老师测试方法的思路,new一个类,传入参数,调用方法.post情况下,如果加上传参产生的变化不需要考虑吗?如果是,老师是怎样设计函数达到了这样的效果.结合面向对象思想理解程序流程,整个流程实际上就是初始化各类对象,最后返回目标对象的过程. 技巧①,顺之前的处理思路而下,看哪里涉及到了需要做改变如在file.exists那里的判

2017-9-11 - A - webServer

1 * /index.html * /reg?username=fancq&password=123456&nickname= * 在GET请求中,URI可能会有上面两种情况. * HTTP协议中规定,GET请求中的URI可以传递参数,而规则时请求的资源后面以 * "?"分割,之后则为所有要传递的参数,每个参数由: * name=value的格式保存,每个参数之间使用"&"分割. * 这里的处理要求: * 将"?"之前的内

跨域学习笔记3--web.config设置之system.webServer 详细介绍,为网站设置默认文档

自己并不懂,在此先记录下来,留待以后学习... 如何:为 IIS 7.0 配置 <system.webServer> 节2008-06-14 22:26http://technet.microsoft.com/zh-cn/sysinternals/bb763179.aspx 如何:为 IIS 7.0 配置 <system.webServer> 节Web.config 文件中的 system.webServer 节用于指定适用于 Web 应用程序的 IIS 7.0 设置.system

WebServer 之http与httpd(apache)基础介绍

httpd是Apache超文本传输协议(HTTP)服务器的主程序.被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池.说到httpd,首先就要了解HTTP协议,HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议.它可以使浏览器更加高效,使网络传输减少.它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等. 以下是个人对WebSer