您的位置:首页 > 其它

epoll实例

2014-07-01 09:17 86 查看
#include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

#define SERV_PORT 8888    //端口号
#define MAX_LEN 100       //最大连接数
#define LISTENQ 20        //等待数

using namespace std;

//设置socket为非阻塞模式
int setnoblocking(int sockfd) {/*{{{*/

if(fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
return 1;
}

/*int opts;

//获取打开方式
opts = fcntl(sockfd, F_GETFD, 0);

if(opts < 0) {
cout << "opts F_GETFL error!!" << endl;
return 1;
}

opts = opts | O_NONBLOCK;

//设置文件描述符
if(fcntl(sockfd, F_SETFL, opts) < 0) {
cout << "opts F_SETFL error!!" << endl;
return 1;
}*/

return 0;
}/*}}}*/

//操作消息
int handle_message(int connfd) {
//缓冲变量
char buf[1024];

//获取的长度
int len = 0;

len = recv(connfd, buf, 1024, 0);

if(len < 0) {
cout << "数据接收失败" << endl;
close(connfd);
return -1;
}

printf("%d消息接收成功%s,maxlen%d", connfd, buf, len);
return len;
}

//主函数
int main ( int argc, char *argv[] ) {/*{{{*/

int listfd, epfd, nfds, i, connfd, curfds, ret;

//客户端长度
socklen_t client_len;
client_len = sizeof(struct sockaddr_in);

//客户端socket地址
struct sockaddr_in clientaddr;

//服务端socket地址
struct sockaddr_in serveraddr;

//epoll ev 事件注册,events事件回调
struct epoll_event ev, events[20];

//创建epoll文件符
epfd = epoll_create(256);

//创建socket文件符
listfd = socket(AF_INET, SOCK_STREAM, 0);

//将socket设置为非阻塞模式
if(setnoblocking(listfd) > 0) {
cout << "socket noblocking error!!";
return 0;
}

//设置epoll要处理的相关文件符
ev.data.fd = listfd;

//epoll要处理的事件类型
ev.events = EPOLLIN | EPOLLET;

//注册epoll事件
epoll_ctl(epfd, EPOLL_CTL_ADD, listfd, &ev);

//将服务端地址清空
bzero(&serveraddr, sizeof(serveraddr));

//设置服务端信息
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERV_PORT);
serveraddr.sin_
4000
addr.s_addr = INADDR_ANY;
//设置IP地址
//char *local_addr = "127.0.0.1";
//inet_aton(local_addr, &(serveraddr.sin_addr));

if(bind(listfd, (sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
cout << "bind listfd error!!" << endl;
return 0;
}

//等待数
if(listen(listfd, LISTENQ) < 0) {
cout << "list error!!" << endl;
return 0;
}

//当前文件符
curfds = 1;
while(1) {
//等待事件发生
nfds = epoll_wait(epfd, events, curfds, -1);

//处理所有发生的事件
for(i = 0; i < nfds; i++) {
if(events[i].data.fd == listfd) {

//获取连接符
connfd = accept(listfd, (struct sockaddr *)&clientaddr, &client_len);

if(connfd < 0) {
cout << "connfd error!!" << endl;
continue;
}

//设置连接文件符为非阻塞模式
setnoblocking(connfd);

//将epoll设置到连接符上
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = connfd;

if(epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev) < 0) {
return -1;
}

curfds++;
} else {
//获取请求信息
ret = handle_message(events[i].data.fd);

if(ret < 1) {
//删除fd
epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, &ev);
curfds--;
}
}
}
}

close(listfd);
return 0;
}/*}}}*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: