epoll

#include <sys/socket.h>  

#include <sys/epoll.h>  

#include <netinet/in.h>  

#include <arpa/inet.h>  

#include <fcntl.h>  

#include <unistd.h>  

#include <stdio.h>  

#include <errno.h>  

#include <iostream>  

using namespace std;  

/*

typedef union epoll_data

{

  void        *ptr;

  int          fd;

  __uint32_t   u32;

  __uint64_t   u64;

} epoll_data_t;

struct epoll_event

{

  __uint32_t   events; // Epoll events /

  epoll_data_t data;   // User data variable /

};

*/

#define MAX_EVENTS 10

struct epoll_event ev, clientevents[MAX_EVENTS],events[MAX_EVENTS+1];

int listenfd, connfd, nfds, epollfd;

void setnonblocking(int sock)

{

    int opts;

    opts=fcntl(sock,F_GETFL);

    if(opts<0)

    {

        perror("fcntl(sock,GETFL)");

//exit(0);

    }

    opts = opts|O_NONBLOCK;

    if(fcntl(sock,F_SETFL,opts)<0)

    {

        perror("fcntl(sock,SETFL,opts)");

      //  exit(1);

    }   

}

//初始化event,data.u32为0表示未使用

void InitEvents()

{

int i;

for(i=0;i<MAX_EVENTS;i++)

{

clientevents[i].data.u32=0;

}

}

//获取未被使用的clientevents序号

int GetEmptyEventsId()

{

int i;

for(i=0;i<MAX_EVENTS;i++)

{

if(clientevents[i].data.u32==0)

return i;

}

return -1;

}

//对断开的套接字清理

void DelEventsFd(int fd)

{

int i;

for(i=0;i<MAX_EVENTS;i++)

{

if(clientevents[i].data.fd==fd)

{

epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,&clientevents[i]);

clientevents[i].data.u32=0;

close(fd);

}

break;

}

}

int main()

{

//创建listen

short port = 8888;

listenfd=socket(AF_INET,SOCK_STREAM,0);

setnonblocking(listenfd);

sockaddr_in sin;

    sin.sin_family = AF_INET;  

    sin.sin_addr.s_addr = INADDR_ANY;  

    sin.sin_port = htons(port);  

    bind(listenfd, (struct sockaddr*)&sin, sizeof(sin));  

    listen(listenfd, 5); 

//创建epoll///

InitEvents();

epollfd=epoll_create(MAX_EVENTS);

if(epollfd<=0)

{

printf("create errr\n");

return 0;

}else

{ printf("EpollFd:%d\n",epollfd);

}

//设置属性加入信号///

ev.events=EPOLLIN;

ev.data.fd=listenfd;

if(epoll_ctl(epollfd,EPOLL_CTL_ADD,listenfd,&ev)==0)

printf("Set nfds OK\n");

int i;

/

while(true)

{

nfds=epoll_wait(epollfd,events,MAX_EVENTS,-1);

if(nfds>0)

printf("nfds:%d\n",nfds);

for(i=0;i<nfds;i++)

{

if(events[i].data.fd==listenfd){

sockaddr_in local;

socklen_t addrlen=sizeof(local);

connfd=accept(listenfd,(struct sockaddr*)&local,&addrlen);

printf("New Link Fd:%d\n",connfd);

int id=GetEmptyEventsId();

if(id==-1)

{

printf("Not Empty\n");

continue;

}

clientevents[id].data.u32=1;

setnonblocking(connfd);

clientevents[id].data.fd=connfd;

clientevents[id].events=EPOLLIN|EPOLLET;

if(epoll_ctl(epollfd,EPOLL_CTL_ADD,connfd,&clientevents[id])==0)

printf("Set OK linkfd:%d eventid:%d\n",connfd,id);

}else

{

char temp[256]={0};

int n=recv(events[i].data.fd,temp,256,0);

printf("Message from:%d len:%d data:%s\n",events[i].data.fd,n,temp);

if(n<=0)

{

printf("fd:%d closed\n",events[i].data.fd);

DelEventsFd(events[i].data.fd);

}

}

}

}

//关闭///

close(epollfd);

return 0;

}


转载于:https://my.oschina.net/u/780323/blog/361668

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值