#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/epoll.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#define MAX_EVENTS 10
#define PORT 12345
#define BUFFSIZE 1024
void setnonblocking(int sockfd)
{
int opts;
opts = fcntl(sockfd, F_GETFL);
if(opts < 0)
{
printf("fcntl(F_GETFL)\n");
exit(1);
}
opts = (opts | O_NONBLOCK);
if(fcntl(sockfd, F_SETFL, opts) < 0)
{
printf("fcntl(F_SETFL)\n");
exit(1);
}
}
int main()
{
struct epoll_event ev, events[MAX_EVENTS];
int addrlen, listenfd, conn_sock, nfds, epfd, fd, i, nread, n;
struct sockaddr_in local, remote;
char buf[BUFSIZ];
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("sockfd error\n");
exit(1);
}
int enable = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
setnonblocking(listenfd);
bzero(&local, sizeof(local));
local.sin_family = AF_INET;
local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_port = htons(PORT);
if(bind(listenfd, (struct sockaddr *)&local, sizeof(local)) < 0)
{
printf("bind error\n");
exit(1);
}
listen(listenfd, 20);
epfd = epoll_create(MAX_EVENTS);
printf("epfd = %d\n", epfd);
if(epfd == -1)
{
printf("epoll create error\n");
exit(1);
}
ev.events = EPOLLIN;
ev.data.fd = listenfd;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev) == -1)
{
printf("epoll_ctl: listen_sock add error\n");
exit(1);
}
for(; ;)
{
sleep(2);
nfds = epoll_wait(epfd, events, MAX_EVENTS, -1);
printf("epoll_wait nfds = %d\n", nfds);
if(nfds == -1)
{
printf("epoll_wait error\n");
exit(1);
}
for(i = 0; i < nfds; ++i)
{
fd = events[i].data.fd;
if(fd == listenfd)
{
addrlen = sizeof(remote);
while((conn_sock = accept(listenfd, (struct sockaddr *) &remote, &addrlen)) > 0)
{
setnonblocking(conn_sock);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = conn_sock;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, conn_sock, &ev) == -1)
{
printf("epoll_ctl:add conn_sock error\n");
exit(1);
}
}
if(conn_sock == -1)
{
if(errno != EAGAIN && errno != ECONNABORTED && errno != EPROTO && errno != EINTR)
{
printf("accept error\n");
}
}
continue;
}
if(events[i].events &EPOLLIN)
{
n = 0;
memset(buf, 0, sizeof(buf));
while((nread = read(fd, buf + n, BUFFSIZE - 1)) > 0)
{
n += nread;
}
printf("read: %s\n", buf);
if(nread == -1 && errno != EAGAIN)
{
printf("read error\n");
}
ev.data.fd = fd;
ev.events = events[i].events | EPOLLOUT;
if(epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev) == -1)
{
printf("epoll_ctl:mod error\n");
}
}
if(events[i].events & EPOLLOUT)
{
memset(buf, 0, sizeof(buf));
const char *s = "hello world";
snprintf(buf, sizeof(buf), "%s", s);
int nwrite, data_size = strlen(buf);
n = data_size;
while(n > 0)
{
nwrite = write(fd, buf + data_size - n, n);
if(nwrite < n)
{
if(nwrite == -1 && errno != EAGAIN)
{
printf("write error\n");
}
break;
}
n -= nwrite;
}
printf("write:%s\n", buf);
//close(fd);
}
}
}
return 0;
}
epoll服务端代码实现
最新推荐文章于 2024-01-25 21:46:13 发布