记录 epoll 编程
参考链接:
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>//write头文件
#include <errno.h>
#define MAX_EVENT 1024
void epollAddFd(int epollfd, int fd)
{
/* fd设置非阻塞模式 */
int old_option = fcntl(fd, F_GETFL);
int new_option = old_option | O_NONBLOCK;
if (fcntl(fd, F_SETFL, new_option) < 0) {
return;
}
/* 注册epoll事件 */
epoll_event event;
event.data.fd=fd; //设置与要处理的事件相关的文件描述符
event.events=EPOLLIN|EPOLLET; //设置要处理的事件类型
epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event) < 0 //注册epoll事件
}
void main()
{
epoll_event events[MAX_EVENT];
int serverSocketFd;
int epollFd;
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serverSocketFd = socket(AF_INET,SOCK_STREAM, 0);
if(serverSocketFd < 0)
{
exit(1);
}
//程序挂掉时,有相同本地地址和端口的socket处于TIME_WAIT状态时,重启程序就需要
int one = 1;
if (setsockopt(serverSocketFd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
close(serverSocketFd);
exit(1);
}
ret = bind(serverSocketFd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(ret < 0)
{
exit(1);
}
ret = listen(serverSocketFd,10);
if(ret < 0)
{
exit(1);
}
epollFd = epoll_create(MAX_EVENT);
if(epollFd < 0)
{
exit(1);
}
//将 fd 注册到 epoll
epollAddFd(epollFd, serverSocketFd);
while (true)
{
int ret=epoll_wait(epollFd,events,MAX_EVENT,-1);
if(ret < 0)
{
exit(1);
}
for(int i = 0; i < ret; ++i)
{
if (events[i].data.fd == serverSocketFd) //接受新连接
{
int connfd;
struct sockaddr_in clientAddr;
socklen_t len = sizeof (clientAddr);
//ET模式,多个连接时只接收一次,用while循环将所有连接接收,解决请求bug//
while ((connfd = accept(serverSocketFd, (struct sockaddr*)&clientAddr, &len)) > 0)
{
//将 fd 注册到 epoll
epollAddFd(epollFd, connfd);
}
if (connfd == -1) //几个参数表示所有请求都接收
{
if (errno != EAGAIN && errno != ECONNABORTED && errno != EPROTO && errno != EINTR)
printf("accept error\n");
}
}
else if (events[i].events & EPOLLIN) { //接收数据
//int socketfd = events[i].data.fd;
//receiveData(socketfd);
}
}
}
close(m_epollFd);
close(m_serverSocketFd);
}