#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#define MAX_EVENTS 100
#define MAX_BUFFER_SIZE 10
/*设置非阻塞*/
int setNonBlock(int fd)
{
int old_flag = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, old_flag | O_NONBLOCK);
return old_flag;
}
/*添加到epoll池中*/
void addfd_to_epoll(int epfd, int fd)
{
struct epoll_event event;
event.data.fd = fd;
event.events = EPOLLIN | EPOLLET;
setNonBlock(fd);
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
}
void err_exit(char *msg)
{
perror(msg);
exit(1);
}
int create_socket(char *ip, int port)
{
struct sockaddr_in addr;
int sockfd, reuse = 1;
memset(&addr, 0, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if(inet_pton(PF_INET, ip, &addr.sin_addr) == -1)
{
err_exit("inet_pton() error");
}
if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
err_exit("socket() error");
}
if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)))
{
err_exit("setsockopt() error");
}
if(-1 == bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)))
{
err_exit("bind() error");
}
//待处理连接最大5
if(-1 == listen(sockfd, 5))
{
err_exit("listen() error");
}
return sockfd;
}
void epoll_process(int epfd, struct epoll_event *events, int num, int listenfd)
{
struct sockaddr addr;
int newfd, confd;
socklen_t len;
for(int i = 0; i < num; ++i)
{
newfd = events[i].data.fd;
if(newfd == listenfd)
{
confd = accept(listenfd, &addr, &len);
addfd_to_epoll(epfd, confd);
}
else
{
printf("开始接受客户端%d数据 \n", newfd);
//et的循环接受数据
char szBuf[MAX_BUFFER_SIZE + 1];
while(1)
{
memset(&szBuf, 0, sizeof(szBuf));
int ret = recv(newfd, szBuf, MAX_BUFFER_SIZE, 0);
if(ret == 0)
{
printf("客户端主动关闭请求\n");
close(newfd);
break;
}
else if(ret == -1)
{
if(errno == EAGAIN || errno == EWOULDBLOCK)
{
printf("循环读取完了所有的数据 \n");
break;
}
else if(104 == errno) //connetction reset by peer
{
printf("客户端主动关闭请求\n");
}
close(newfd);
break;
}
else
{
printf("接受到数据%d字节,数据: %s\n", ret, szBuf);
}
}
}
}
}
int main(int argc, char** argv)
{
if(argc < 3)
{
fprintf(stderr, "usage:%s ip_address port_number\n", argv[0]);
exit(0);
}
int listenfd, epfd;
listenfd = create_socket(argv[1], atoi(argv[2]));
epfd = epoll_create(100000);
if(-1 == epfd) exit(-1);
addfd_to_epoll(epfd, listenfd);
struct epoll_event events[MAX_EVENTS + 1];
while(1)
{
int num = epoll_wait(epfd, events, MAX_EVENTS, 0);
if(num == -1)
{
err_exit("epoll_wait() error");
}
else
{
epoll_process(epfd, events, num, listenfd);
}
usleep(10);
}
close(listenfd);
return 0;
}
非阻塞,et模型 epoll
最新推荐文章于 2024-04-23 20:56:30 发布