65,187
社区成员




#include <stdio.h>
#include <sys/epoll.h> // epoll_create
#include <string.h>
#include <errno.h>
#include <stdlib.h> // for atoi
#include <sys/socket.h> // for socket
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h> // for sleep
#define ERRMSG(MSG) printf("%s failed[%s]\n", #MSG, strerror(errno))
#define LISTEN_PORT 10000
#define TRUEERRMSG(MSG) \
do{\
if(MSG) \
{ \
printf("%s failed[%s]\n", #MSG, strerror(errno)); \
return -1; \
} \
}while(0)
typedef struct
{
int nfd;
int nDataLen;
char szData[0];
}ClientInfo;
int main(int argc, char **argv)
{
int nRet;
int nListenPort;
int nEpollSize = 5;
if(argv[1] != NULL)
{
nListenPort = atoi(argv[1]);
}
else
{
nListenPort = LISTEN_PORT;
}
int nListenFD = socket(AF_INET, SOCK_STREAM, 0);
if(nListenFD == -1)
{
ERRMSG(socket);
return -1;
}
struct sockaddr_in stSerAddr;
stSerAddr.sin_family = AF_INET;
stSerAddr.sin_port = htons(nListenPort);
stSerAddr.sin_addr.s_addr = htonl( INADDR_ANY);
int ireuseadd_on = 1;//支持端口复用
setsockopt(nListenFD, SOL_SOCKET, SO_REUSEADDR, &ireuseadd_on, sizeof(ireuseadd_on) );
nRet = bind(nListenFD, (struct sockaddr *)&stSerAddr, sizeof(stSerAddr));
if(nRet == -1)
{
ERRMSG(bind);
return -1;
}
nRet = listen(nListenFD, 1);
TRUEERRMSG(nRet == -1&&"listen");
int nefd = epoll_create(nEpollSize);
if(nefd == -1)
{
ERRMSG(epoll_create);
return -1;
}
struct epoll_event stEvent;
stEvent.data.u64 = 0;
stEvent.data.fd = nListenFD;
stEvent.events = EPOLLIN;
nRet = epoll_ctl(nefd, EPOLL_CTL_ADD, nListenFD, &stEvent);
TRUEERRMSG(nRet == -1&&"epoll_ctl");
struct epoll_event aEpollEvents[5];
int nTimeout = 10;
while(1)
{
nRet = epoll_wait(nefd, aEpollEvents, 5, nTimeout);
if(nRet <= 0)
{
continue;
}
for(int i = 0; i < nRet; i++)
{
if(aEpollEvents[i].events & EPOLLERR)
{
struct epoll_event stEvent;
stEvent.data.u64 = 0;
stEvent.data.fd = aEpollEvents[i].data.fd;
stEvent.events = EPOLLIN | EPOLLERR | EPOLLHUP;
nRet = epoll_ctl(nefd, EPOLL_CTL_DEL, aEpollEvents[i].data.fd, &stEvent);
printf("EPOLL_CTL_DEL111111[%d][%s]fd[%d]\n", nRet, strerror(errno), aEpollEvents[i].data.fd);
close(aEpollEvents[i].data.fd);
continue;
}
if((aEpollEvents[i].events & EPOLLIN) == 0)
{
printf("not event \n");
continue;
}
if(aEpollEvents[i].data.fd == nListenFD)
{
// process new client connect
printf("listen fd event accept nlistenfd[%d]\n", nListenFD);
struct sockaddr_in stSockAddr;
socklen_t nLen = sizeof(stSockAddr);
int nfd = accept(nListenFD, (struct sockaddr*)&stSockAddr, &nLen);
if(nfd == -1)
{
printf("accept failed[%s]\n", strerror(errno));
continue;
}
printf("client[%s:%d] connect fd[%d]\n", inet_ntoa(stSockAddr.sin_addr), ntohs(stSockAddr.sin_port), nfd);
struct epoll_event stEvent;
stEvent.data.u64 = 0;
stEvent.data.fd = nfd;
stEvent.events = EPOLLIN | EPOLLERR | EPOLLHUP;
nRet = epoll_ctl(nefd, EPOLL_CTL_ADD, nfd, &stEvent);
continue;
}
if(aEpollEvents[i].events & EPOLLIN)
{
// process read event`
char szBuff[1024] = {0};
nRet = recv(aEpollEvents[i].data.fd, szBuff, sizeof(szBuff), 0);
if(nRet <= 0)
{
printf("recv [%d][%s]fd[%d]\n", nRet, strerror(errno), aEpollEvents[i].data.fd);
struct epoll_event stEvent;
stEvent.data.u64 = 0;
stEvent.data.fd = aEpollEvents[i].data.fd;
stEvent.events = 0;
nRet = epoll_ctl(nefd, EPOLL_CTL_DEL, aEpollEvents[i].data.fd, &stEvent);
printf("EPOLL_CTL_DEL[%d][%s] [%d]\n", nRet, strerror(errno), aEpollEvents[i].data.fd);
struct sockaddr_in stAddr;
socklen_t nLen = sizeof(stAddr);
nRet = getpeername(aEpollEvents[i].data.fd, (struct sockaddr*)&stAddr, &nLen);
printf("client[%s:%d] close connect nRet[%d][%s]fd[%d]\n", inet_ntoa(stAddr.sin_addr), ntohs(stAddr.sin_port), nRet, strerror(errno), aEpollEvents[i].data.fd);
close(aEpollEvents[i].data.fd);
}
else
{
printf("recv[%s]fd[%d]\n", szBuff, aEpollEvents[i].data.fd);
struct epoll_event stEvent;
stEvent.data.u64 = 0;
stEvent.data.fd = aEpollEvents[i].data.fd;
stEvent.events = EPOLLIN;
nRet = epoll_ctl(nefd, EPOLL_CTL_MOD, aEpollEvents[i].data.fd, &stEvent);
printf("EPOLL_CTL_MOD[%d][%s] [%d]\n", nRet, strerror(errno), aEpollEvents[i].data.fd);
}
}
}
}
return 0;
}