/*********************************
* mkfifo p1 p2
* cat > p1
* cat > p2
*FileName: epoll_wait.c
*Author : Dai
*Version : 1
*Date : 2014.09.19
*Description: 用epoll_wait监听多个管道,管道中有内容就读出 (1)epoll_creat()创建一个句柄
*Note : 打开一个文件用非阻塞方式,不然会阻塞到read上, 而我们要求用epoll_wait()阻塞到epoll_wait()上
*********************************/
#include <stdio.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
struct epoll_event env;
int main(void)
{
int fd1, fd2;
if((fd1 = open("p1", O_RDONLY|O_NONBLOCK)) == -1){
perror("open p1 fail\n");
exit(-1);
}
if((fd2 = open("p2", O_RDONLY|O_NONBLOCK)) == -1){
perror("open p2 fail\n");
exit(-1);
}
int epoll_fd = epoll_create(1);
if(epoll_fd == -1)
perror("epoll create fail\n");
env.data.fd = fd1;
env.events = EPOLLIN|EPOLLET;
if((epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd1, &env)) == -1)
perror("epoll_ctl p1 fail\n");
env.data.fd = fd2;
env.events = EPOLLIN | EPOLLET;
if((epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd2, &env)) == -1)
perror("epoll_ctl p2 fail\n");
while(1){
char buf[32];
epoll_wait(epoll_fd, &env, 1, -1);
int fd = env.data.fd;
int len;
while((len = (read(fd, buf, 32))) > 0)
buf[len] = '\0';
printf("get %s from %d\n", buf, fd);
}
return 0;
}
***********************************************************************************************************
/*****************************************
*Discription:用socket实现远程登录访问 用epoll_wait实现并发 两个端口进行通信
*socket 产生用于监听的描述符 bind 绑定地址和端口 listen 把套接字设为被动 accept()用于产生和客户机进行交 互的文件描述符
*
*
*
*
* *********************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h> //inet_ntop()
#include <sys/epoll.h>
#define SERV_port 8000 //端口号
#define max_r 100 //存取从客户端读过来的空间
#define max_ep 10 //从内核可以处理事件集合的大小
char buf_f[1024];
int flag_fd[100];
int f_fd;
int main(void)
{
int listenfd, connfd;
char buf[100];
char buf1[100];
int r_len;
char str[INET_ADDRSTRLEN]; //。。。。。。。
struct sockaddr_in servaddr, cliaddr;
int ep_fd, cur_ep, accept_Count = 0; //ep_fd创建的句柄用于处理wait的epoll文件描述符 cur_ep用于记录当前epoll_wait监听事件的个数
int nfds, i, j; //epoll_wait返回的处理事件的个数
struct epoll_event ep_env; //用于注册事件
struct epoll_event events[max_ep];//用于回传要处理的事件
listenfd = socket(AF_INET, SOCK_STREAM, 0);
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_port);
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){
perror("bind fail\n");
}
if(listen(listenfd, 20) == -1){
perror("listen fail\n");
}
printf("now we can accept connections\n");
//创建epoll句柄 并把监听socket加入epoll队列
if((ep_fd = epoll_create(1)) == -1){
perror("epoll_create fail\n");
exit(-1);
}
memset(flag_fd, 0, sizeof(flag_fd));
ep_env.data.fd = listenfd;
ep_env.events = EPOLLIN | EPOLLET;
if((epoll_ctl(ep_fd, EPOLL_CTL_ADD, listenfd, &ep_env)) == -1){
perror("epoll_ctl fail\n");
}
//把服务器标准输入加入epoll队列
ep_env.data.fd = STDIN_FILENO;
ep_env.events = EPOLLIN | EPOLLET;
if((epoll_ctl(ep_fd, EPOLL_CTL_ADD, STDIN_FILENO, &ep_env)) == -1){
perror("epoll_ctl fail\n");
}
flag_fd[listenfd] = 1;
flag_fd[STDIN_FILENO] = 1;
printf("epoll_server start server port:%d\n", SERV_port);
cur_ep = 2;
while(1){
nfds = epoll_wait(ep_fd, events, cur_ep, -1);
for(i = 0; i < nfds; i++){
if(events[i].data.fd == listenfd){
int cliaddr_len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
sprintf(buf, "accept from %s at port %d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
printf("%d:%s", ++accept_Count, buf);
ep_env.events = EPOLLIN | EPOLLET;
ep_env.data.fd = connfd;
epoll_ctl(ep_fd, EPOLL_CTL_ADD, connfd, &ep_env);
flag_fd[connfd] = 1;
cur_ep++;
continue;
}
else if(events[i].data.fd == STDIN_FILENO){
if(handle(events[i].data.fd, connfd) < 0) {
epoll_ctl(ep_fd, EPOLL_CTL_DEL, j, &ep_env);
close(events[i].data.fd);
cur_ep--;
flag_fd[events[i].data.fd] = 0;
}
}
else{
if(handle(events[i].data.fd, STDIN_FILENO) < 0){
epoll_ctl(ep_fd, EPOLL_CTL_DEL, connfd, &ep_env);
close(events[i].data.fd);
cur_ep--;
flag_fd[events[i].data.fd] = 0;
}
}
}
/*
int cliaddr_len = sizeof(cliaddr);
while((r_len = read(connfd, buf, max_r))){
printf("received from %s at port %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
write(connfd, buf, r_len);
}*/
}
close(listenfd);
return 0;
}
//从src复制到dest
int handle(int src, int dest) {
int nread;
int j;
char buf[1024];
nread = read(src, buf, 1024);
if(nread == 0){
printf("client close the connection\n");
return -1;
}
if(nread < 0){
perror("read error");
return -1;
}
for(j = 0; j < 100; j++)
if(j != 3 && j != src && flag_fd[j] == 1)
write(j, buf, nread);
return 0;
}
**********************************************************
#include <unistd.h>
#include <sys/types.h> /* basic system data types */
#include <sys/socket.h> /* basic socket definitions */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <sys/epoll.h> /* epoll function */
#include <fcntl.h> /* nonblocking */
#include <sys/resource.h> /*setrlimit */
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define MAXEPOLLSIZE 10
#define MAXLINE 10240
int handle(int connfd);
int main(int argc, char **argv)
{
int servPort = 8000;
int listenfd, connfd, kdpfd, nfds, n, nread;
int curfds,acceptCount = 0;
struct sockaddr_in servaddr, cliaddr;
socklen_t socklen = sizeof(struct sockaddr_in);
struct epoll_event ev;
struct epoll_event events[MAXEPOLLSIZE];
char buf[MAXLINE];
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
servaddr.sin_port = htons (servPort);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1)
{
perror("bind error");
return -1;
}
listen(listenfd, 10);
/* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
kdpfd = epoll_create(MAXEPOLLSIZE);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listenfd;
epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, &ev);
curfds = 1;
printf("epollserver startup,port %d\n", servPort);
for (;;) {
/* 等待有事件发生 */
nfds = epoll_wait(kdpfd, events, curfds, -1);
/* 处理所有事件 */
for (n = 0; n < nfds; ++n)
{
if (events[n].data.fd == listenfd)
{
connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen);
sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
printf("%d:%s", ++acceptCount, buf);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = connfd;
epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, &ev);
curfds++;
continue;
}
// 处理客户端请求
if (handle(events[n].data.fd) < 0) {
epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,&ev);
close(events[n].data.fd);
curfds--;
}
}
}
close(listenfd);
return 0;
}
int handle(int connfd) {
int nread;
char buf[MAXLINE];
nread = read(connfd, buf, MAXLINE);//读取客户端socket流
if (nread == 0) {
printf("client close the connection\n");
return -1;
}
if (nread < 0) {
perror("read error");
return -1;
}
write(connfd, buf, nread);//响应客户端
return 0;
}