您的位置:首页 > 其它

epoll示范

2016-03-22 20:32 357 查看
一.server端

#include <iostream>
#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 <stdlib.h>
#include <errno.h>
#include <string.h>

using namespace std;

#define MAXLINE 5
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5000
#define INFTIM 1000

void setnonblocking(int sock)
{
int opts;
opts = fcntl(sock, F_GETFL);
if(opts < 0)
{
perror("fcntl(sock,GETFL)");
exit(1);
}
opts = opts|O_NONBLOCK;
if(fcntl(sock, F_SETFL, opts) < 0)
{
perror("fcntl(sock,SETFL,opts)");
exit(1);
}
}

int main()
{
int listenfd = socket(AF_INET, SOCK_STREAM, 0); //创建socket
setnonblocking(listenfd); //socket设置为非阻塞方式

struct epoll_event ev; //ev用于注册事件
struct epoll_event events[20]; //events用于回传要处理的事件
ev.data.fd = listenfd; //设置与要处理的事件相关的文件描述符
ev.events = EPOLLIN|EPOLLET; //设置要处理的事件类型

int epfd = epoll_create(256); //生成用于处理accept的epoll专用的文件描述符
epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev); //注册epoll事件

struct sockaddr_in clientaddr;
struct sockaddr_in serveraddr;
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
char *local_addr = "127.0.0.1";
inet_aton(local_addr, &(serveraddr.sin_addr));
serveraddr.sin_port = htons(SERV_PORT);
bind(listenfd, (sockaddr *)&serveraddr, sizeof(serveraddr));
listen(listenfd, LISTENQ);

int sockfd;
ssize_t n;
char buf[MAXLINE];
socklen_t clilen;

while(1)
{
int nfds = epoll_wait(epfd, events, 20, 500); //等待epoll事件的发生
for (int i = 0; i < nfds; i++)
{
if (events[i].data.fd == listenfd)
{
int connfd = accept(listenfd, (sockaddr *)&clientaddr, &clilen);
if(connfd < 0)
{
perror("connfd<0");
exit(1);
}

char *str = inet_ntoa(clientaddr.sin_addr);
printf("accapt a connection from: %s\n", str);

setnonblocking(connfd); //socket设置为非阻塞方式
ev.data.fd = connfd; //设置用于读操作的文件描述符
ev.events = EPOLLIN|EPOLLET; //设置用于注册的读操作事件
epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev); //注册ev
}
else if (events[i].events & EPOLLIN)
{
if ((sockfd = events[i].data.fd) < 0)
{
continue;
}

if ((n = read(sockfd, buf, MAXLINE)) < 0)
{
if (errno == ECONNRESET)
{
close(sockfd);
events[i].data.fd = -1;
}
}
else if (n == 0)
{
close(sockfd);
events[i].data.fd = -1;
}

buf
= '\0';
ev.data.fd = sockfd; //设置用于写操作的文件描述符
ev.events = EPOLLOUT|EPOLLET; ////设置用于注册的写操作事件
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev); //修改sockfd上要处理的事件为EPOLLOUT

printf("recv data:%s\n", buf);
}
else if (events[i].events&EPOLLOUT)
{
if ((sockfd = events[i].data.fd) < 0)
{
continue;
}

write(sockfd, buf, n);
ev.data.fd = sockfd; //设置用于读操作的文件描述符
ev.events = EPOLLIN|EPOLLET; //设置用于注册的读操作事件
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev); ////修改sockfd上要处理的事件为EPOLIN

printf("send data:%s\n", buf);
}
}
}

return 0;
}


二.client端
#include <iostream>
#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 <stdlib.h>
#include <errno.h>
#include <string.h>

using namespace std;

#define SERV_PORT 5000
#define MAXLINE 5
#define MESSAGE "hello"

int main()
{
char buf[MAXLINE];

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in serveraddr;
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
char *local_addr = "127.0.0.1";
inet_aton(local_addr, &(serveraddr.sin_addr));
serveraddr.sin_port = htons(SERV_PORT);

if (0 != connect(sockfd, (sockaddr *)&serveraddr, sizeof(serveraddr)))
{
printf("connected failed");
return 1;
}

write(sockfd, MESSAGE, sizeof(MESSAGE));
int count = read(sockfd, buf, MAXLINE);

printf("Response from server: %s\n",buf);

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