码迷,mamicode.com
首页 > Web开发 > 详细

使用epoll,完成简单http消息回显,并用浏览器测试

时间:2016-08-01 07:00:01      阅读:334      评论:0      收藏:0      [点我收藏+]

标签:使用epoll   完成简单http消息回显   并用浏览器测试   

epoll_tcp.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/epoll.h>

static int startup(const char *_ip,int _port)
{
 int sock=socket(AF_INET,SOCK_STREAM,0);
 if(sock<0){
  perror("socket");
  exit(2);
 }

 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){
  perror("bind");
  exit(3);
 }

 if(listen(sock,5)<0){
  perror("listen");
  exit(4);
 }
 return sock;
}

static int set_noblock(int sock)
{
 int fl=fcntl(sock,F_GETFL);
 return fcntl(sock,F_SETFL,fl|O_NONBLOCK);
}

static void usage(const char *proc )
{
 printf("usage: %s [ip] [port]\n",proc);
}

int main(int argc,char *argv[])
{
 if(argc!=3){
  usage(argv[0]);
  exit(1);
 }
 int listen_sock=startup(argv[1],atoi(argv[2])); //cteate listen socket

 int epfd=epoll_create(256);
 if(epfd<0){
  perror("epoll_create");
  exit(5);
 }

 struct epoll_event _ev;
 _ev.events=EPOLLIN;
 _ev.data.fd=listen_sock;

 epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, &_ev);

 struct epoll_event _ready_ev[128];
 int  _ready_evs=128;
 int _timeout=-1; //block

 int nums=0;
 int done=0;
 while(!done){
  switch( (nums=epoll_wait(epfd, _ready_ev,\
      _ready_evs, _timeout)) ){
   case 0:
    printf("timeout...\n");
    break;
   case -1:
    perror("epoll_wait");
    break;
   default:
    {
     int i=0;
     for(; i< nums; ++i){
      int _fd=_ready_ev[i].data.fd;
      if(_fd==listen_sock && \
        _ready_ev[i].events & EPOLLIN){
       //get a new link...
       struct sockaddr_in peer;
       socklen_t len=sizeof(peer);
       int new_sock=accept(listen_sock,(struct sockaddr*)&peer, &len);
       if(new_sock > 0){
        printf("client info, socket: %s:%d\n", inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
        _ev.events=EPOLLIN | EPOLLET;//ET
        _ev.data.fd=new_sock;

        set_noblock(new_sock);

        epoll_ctl(epfd, EPOLL_CTL_ADD,\
          new_sock, &_ev);
       }
      }else{
       if(_ready_ev[i].events & EPOLLIN){
        char buf[102400];
        memset(buf, ‘\0‘, sizeof(buf));
        //read/write
        ssize_t _s=recv(_fd, buf,\
          sizeof(buf)-1,0);//while need recv done...

        if( _s > 0){
         printf("client# %s\n",buf);
         _ev.events=EPOLLOUT | EPOLLET;
         _ev.data.fd=_fd;
         epoll_ctl(epfd, EPOLL_CTL_MOD,\
           _fd, &_ev);
        }else if( _s==0 ){
         printf("client close...\n");
         epoll_ctl(epfd,EPOLL_CTL_DEL,\
           _fd, NULL);
         close(_fd);
        }else{
         perror("recv");
        }
       }else if(_ready_ev[i].events &\
         EPOLLOUT){
        const char *msg="HTTP/1.1 200 OK\r\n\r\n<h1>hello world  =_=|| </h1>\r\n";
        send(_fd, msg, strlen(msg),0);
        epoll_ctl(epfd,EPOLL_CTL_DEL,_fd, NULL);
        close(_fd);
       }
      }
     }
    }
    break;
  }
 }
}

技术分享


技术分享




使用epoll,完成简单http消息回显,并用浏览器测试

标签:使用epoll   完成简单http消息回显   并用浏览器测试   

原文地址:http://frankenstein.blog.51cto.com/10918184/1832667

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!