#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#define TRACE_ERROR(str) do{ \
fprintf(stdout,"%s", str); \
}while(0);
static int SetNonblock(int socket)
{
//设置监听不阻塞
int flags = fcntl(socket, F_GETFD, 0);
if(flags==-1)
{
TRACE_ERROR("fcntl F_GETFD error");
return -1;
}
flags |= O_NONBLOCK;
if(fcntl(socket, F_SETFL, flags)==-1)
{
TRACE_ERROR("fnctl F_SETFL error");
return -1;
}
return 0;
}
int handle(int connfd)
{
ssize_t nread;
char buf[1024];
nread = read(connfd, buf, 1023);
if(nread==0)
{
TRACE_ERROR("client closed the connection\n");
close(connfd);
return -1;
}
if(nread<0)
{
TRACE_ERROR("read error\n");
close(connfd);
return -1;
}
if(write(connfd, buf, nread)<=0)
{
TRACE_ERROR("write error\n");
close(connfd);
return -1;
}
return 0;
}
int main()
{
int flags;
int local_socket;
int epoll_file_descriptor;
epoll_event ev;
epoll_event events[1023];
int current_fd;
int n_fd;
int n;
int conn_fd;
sockaddr_in client_addr;
socklen_t client_addr_len;
struct sockaddr_in addr, their_addr;
addr.sin_family = PF_INET;
addr.sin_port = htons(2233);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_socket = socket(PF_INET,SOCK_STREAM, 0);
if(local_socket==-1)
{
TRACE_ERROR("socket create error\n");
return -1;
}
if(SetNonblock(local_socket)==-1) return -1;
if(bind(local_socket, (sockaddr*)&addr, sizeof(struct sockaddr))==-1)
{
close(local_socket);
TRACE_ERROR("bind socket error\n");
return -1;
}
if(listen(local_socket, 511))
{
close(local_socket);
TRACE_ERROR("listen socket error\n");
return -1;
}
epoll_file_descriptor = epoll_create(1024);
if(epoll_file_descriptor == -1)
{
close(local_socket);
TRACE_ERROR("epoll_create fail\n");
return -1;
}
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = local_socket;
if(epoll_ctl(epoll_file_descriptor, EPOLL_CTL_ADD, local_socket, &ev)==-1)
{
close(epoll_file_descriptor);
close(local_socket);
TRACE_ERROR("epoll_ctl fail\n");
return -1;
}
current_fd = -1;
n_fd = -1;
client_addr_len = sizeof(struct sockaddr_in);
while(1)
{
n_fd = epoll_wait(epoll_file_descriptor, events, 1023, -1);
if(n_fd==-1)
{
continue;
}
for(n=0; n<n_fd; n++)
{
if(events[n].data.fd == local_socket)
{
conn_fd = accept(local_socket,(sockaddr*)&client_addr, &client_addr_len);
if(conn_fd==-1)
{
TRACE_ERROR("accept client faild\n");
continue;
}
fprintf(stdout, "accept from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
SetNonblock(conn_fd);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = conn_fd;
if(epoll_ctl(epoll_file_descriptor, EPOLL_CTL_ADD, conn_fd, &ev)==-1)
{
TRACE_ERROR("new client epoll_ctl add faild\n");
close(epoll_file_descriptor);
close(local_socket);
return -1;
}
current_fd++;
continue;
}
else if(events[n].events & EPOLLIN)
{
if(handle(events[n].data.fd)<0)
{
epoll_ctl(epoll_file_descriptor, EPOLL_CTL_DEL, events[n].data.fd, &events[n]);
current_fd--;
}
}
}
}
close(epoll_file_descriptor);
close(local_socket);
return 0;
}
epoll例子
最新推荐文章于 2022-08-17 15:38:23 发布