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;
}
#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;
}
相关文章推荐
- HDU 2068:RPG的错排【排列组合】
- 统计单词数
- LightOj 1231 Coin Change (II)(完全背包)
- 这种员工,将来都是做高管的料!
- Java开发之简单数据类型
- jQuery transform类型实例方法探究
- 如何使用UDP进行跨网段广播
- 计科1111-1114班第二次实验作业(算法基本功 与 综合思考)
- 代码复查
- 微信JS-SDK实现自定义分享功能,分享给朋友,分享到朋友圈
- hdu 5636 Shortest Path
- hdu1828线段树扫描线求周长
- 开博随记
- 作业4 词频统计
- javascript学习2
- 第三周 项目4 (2)换分币
- autoconf AC_ARG_WITH, AC_CACHE_CHECK, AC_TRY_LINK宏学习
- 关于Java和C#的内部类的小记
- 多线程——Java多线程实现的三种方式
- 杭电4858