简单linux服务器模型--epoll 2011

include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#define NUM_LISTENREQUEST 100
 
void setnonblockingpattern(int socketfd)  //把套接字设置为阻塞模型
{
  int nsockopts = fcntl(socketfd, GETFL);
  if(sockopts < 0)
  {
    perror("fcntl(socketfd, GETFL)");
    exit(1);
  }
  nsockopts = nsockopts | O_NONBLOCK;
  if(fcntl(socketfd, SETFL, nsockopts) < 0)
  {
    prror("fcntl(socketfd, SETFL, nsockopts)");
    exit(1);
  }
int main(int argc, char* argv[])          //可自行设置传递参数
{
  int epollfd;                  //处理事件专用的epoll文件描述符
  int ListenSocketFd;    //监听套接字句柄
  int ClientConnSocketFd;    //客户端连接套接字
  int worksocketfd;         
  struct sockaddr_in clinentaddr;
  struct sockaddr_in serveraddr;
  struct epoll_event register_event;    //用于注册事件
  struct epoll_event array_event[100];
  int clientaddr_len = sizeof(clinentaddr);
  int nepollwaitfd = 0;
  int nCount;
  ssize_t  nreadwritecount = 0;
  char* strdatabuffer[50];

  epollfd = epoll_create(512);
  ListenSocketFd  = socket(AF_INET, SOCK_STREAM, 0);
  setnonblockingpattern(ListenSocketFd);
  register_event.data.fd = ListenSocketFd;      //设置和要处理的事件类型相关的文件描述符
  register_event.events = EPOLLIN | EPOLLET;    //设置要处理的事件类型
 
  epoll_ctl(epollfd, EPOLL_CTL_ADD, ListenSocketFd, &register_event);    //注册epoll事件
  bzero(&serveraddr, sizeof(serveraddr));
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_addr = INADDR_ANY;
  serveraddr.sin_port =  htons(8192);
  bind(ListenSocketFd, (sockaddr*)&serveraddr, sizeof(serveraddr));
  NUM_LISTENREQUEST
      listen(ListenSocketFd ,NUM_LISTENREQUEST);
  while(true)
  {
    nepollwaitfd = epoll_wait(epollfd, array_event, NUM_LISTENREQUEST, 700);  //轮询I/O事件的发生
    for(nCount = 0; nCount < nepollwaitfd;  nCount++)
    {
      if(array_event[nCount].data.fd == ListenSocketFd)
      {
        ClientConnSocketFd = accept(ListenSocketFd, (sockaddr*)&clinentaddr, &clientaddr_len);
        if(ClientConnSocketFd < 0)
        {
              perror("accept(ListenSocketFd, (sockaddr*)&clinentaddr, &clientaddr_len)");
              exit(1);
               
        }
        setnonblockingpattern(ClientConnSocketFd);
        char* strclientaddress;
        strclientaddress = inet_ntoa(clinentaddr.sin_addr);
        cout<<"accpet a client connection from"<<strclientaddress<<endl;
              register_event.data.fd = ClientConnSocketFd;    //用于读操作的文件描述符
        register_event.events = EPOLLIN | EPOLLET;    //用于读操作的事件
        epoll_ctl(epollfd, EPOLL_CTL_ADD,ClientConnSocketFd, &register_event );//注册事件
   
      }
      else if(array_event[nCount].events & EPOLLIN) //如果连接用户收到数据,那么进行读入
      {
        cout<<"EPOLLIN events happen!"<<endl;
        worksocketfd = array_event[nCount].data.fd;
        nreadwritecount = read(worksocketfd, strdatabuffer, 50); 
        if(nreadwritecount < 0)
        {
          if(errno == ECONNRESET)
          {
            close(worksocketfd);
            array_event[nCount].data.fd = -1;
         
          }
          else
            std::cout<<"read(worksocketfd, strdatabuffer, 50) error"<<std::endl;       
       
        }
        else if(nreadwritecount == 0)
        {
            close(worksocketfd);
            array_event[nCount].data.fd = -1;
            }
              strdatabuffer[nreadwritecount] = '/0';
                  cout<<"read:"<<strdatabuffer<<endl;
                    register_event.data.fd = worksocketfd;    //设置用于写操作的文件描述符
        register_event.events = EPOLLOUT | EPOLLET;    //用于读操作的事件
        epoll_ctl(epollfd, EPOLL_CTL_ADD,worksocketfd, &register_event );//注册事件 
         
      }
      else if(array_event[nCount].events & EPOLLOUT)
      {
        worksocketfd = array_event[nCount].data.fd;
        write(worksocketfd, strdatabuffer, nreadwritecount);
          //设置用于读操作的文件描述符
        register_event.data.fd = worksocketfd;
        register_event.events = EPOLLIN | EPOLLET; 修改worksocketfd上要处理的事件为EPOLIN
        epoll_ctl(epollfd, EPOLL_CTL_ADD, worksocketfd, &register_event );//注册事件 
      }
   
   
  }
  return 0;
}
}
//没有编译调试,错误自改
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值