实例编程后续完善各种问题处理,以及定时处理等等:
myepoll.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#define MAXEPOLLFD 1000
#define PORT 6785
#define PIDNUM 20
int Port = PORT;
int iGetsocknum=0;
int iListenfd,iEpollfd;
struct epoll_event events[MAXEPOLLFD];
struct epoll_event ev;
pid_t forkpid[PIDNUM];
extern void mydaemon();
extern int iGLoop;
extern void iLoopSet();
extern void SetNoBlock(int fd,int type);
extern int Setsockopt(int fd,int type );
extern void Mylisten(int fd,int listennum);
extern int Mybind(int fd,int type);
typedef void ( * sighandler_t) (int);
extern sighandler_t SetSigHandler(int sigtype,sighandler_t handler);
extern int GetSocket(int type);
void KillChild()
{
for ( int i=0;i<PIDNUM;i++ )
{
kill(forkpid[i],SIGUSR1);
}
}
int GetEpoll(int size){
return epoll_create(size);
}
int EpollSet(int epollfd,int fd,int type ,int type1){
struct epoll_event event;
int epolltype=0,iRet=0;
memset((char *)&event,0x00,sizeof(event));
event.data.fd = fd;
switch( type ){
case 0:
epolltype = EPOLL_CTL_MOD;
break;
case 1:
epolltype = EPOLL_CTL_ADD;
break;
case 3:
epolltype = EPOLL_CTL_DEL;
default:
epolltype = EPOLL_CTL_ADD;
break;
}
switch( type1 ){
case 0:
event.events = EPOLLIN|EPOLLET;
break;
case 1:
event.events = EPOLLOUT|EPOLLET;
break;
default:
event.events = EPOLLIN|EPOLLET;
break;
}
iRet = epoll_ctl(epollfd,epolltype,fd,&event);
if ( iRet == -1 )
{
return -1;
}
return 0;
}
int EpollWait(){
int fd=0;
fd = epoll_wait(iEpollfd, events, MAXEPOLLFD, 5000);
if ( fd == -1 )
{
// DeBugLog();
}
return fd;
}
int InitListenSockt(int port)
{
int iRet=0;
socklen_t socklen;
struct sockaddr_in stServ;
socklen = sizeof( struct sockaddr_in );
iListenfd = GetSocket(0);
if ( iListenfd == -1 )
{
return -1;
}
memset((char *)&stServ,0x00,sizeof(stServ));
if ( Mybind(iListenfd,0 ) == -1 )
{
return -1;
}
Mylisten(iListenfd,200);
if (Setsockopt(iListenfd,0) == -1 )
{
return -1;
}
return iListenfd;
}
void Woker()
{
int fd=0;
int connectfd=0;
char sReadBuf[1024];
char sWriteBuf[1024];
int iReadnum=0;
int iWriteNum=0;
iEpollfd=GetEpoll(MAXEPOLLFD);
EpollSet(iEpollfd,iListenfd,1,0);
SetSigHandler(SIGUSR1,iLoopSet);
memset(sReadBuf,0x00,sizeof(sReadBuf));
memset(sWriteBuf,0x00,sizeof(sWriteBuf));
while(iGLoop)
{
fd= EpollWait();
for ( int i=0;i<fd;i++)
{
if ( events[i].data.fd == iListenfd )
{
connectfd = accept(events[i].data.fd ,NULL, NULL);
if ( connectfd < 0 )
{
// DeBugLog();
}
SetNoBlock(connectfd,0);
EpollSet(iEpollfd,connectfd,1,0);
}
else
{
if ( events[i].events&EPOLLIN )
{
if ( events[i].data.fd < 0 )
continue;
iReadnum = read( events[i].data.fd,sReadBuf,1024 );
if ( iReadnum == 0 )
{
EpollSet(iEpollfd,events[i].data.fd,3,0);
events[i].data.fd = -1;
fprintf(stdout,"error 1 %s\n",sReadBuf);
close(events[i].data.fd);
}
if ( iReadnum < 0 )
{
if ( errno == EAGAIN || errno == EWOULDBLOCK || errno==EINTR )
continue;
else
{
EpollSet(iEpollfd,events[i].data.fd,3,0);
events[i].data.fd = -1;
fprintf(stdout,"error 2 get %s\n",sReadBuf);
close(events[i].data.fd);
}
}
fprintf(stdout,"get: %s \n",sReadBuf);
EpollSet(iEpollfd,events[i].data.fd,0,1);
}
else
{
if ( events[i].events&EPOLLOUT )
{
if ( events[i].data.fd < 0 )
continue;
memset(sWriteBuf,0x00,sizeof(sWriteBuf));
sprintf(sWriteBuf,"send: server fd %d num %d \n",events[i].data.fd,iGetsocknum);
//iWriteNum = wirte( events[i].data.fd,sWriteBuf,30 );
iWriteNum = write( events[i].data.fd,sWriteBuf,30 );
if ( iWriteNum == 0 )
{
EpollSet(iEpollfd,events[i].data.fd,3,0);
events[i].data.fd = -1;
fprintf(stdout,"error 1 write %s\n",sReadBuf);
close(events[i].data.fd);
}
if ( iWriteNum < 0 )
{
if ( errno == EAGAIN || errno == EWOULDBLOCK )
continue;
else
{
EpollSet(iEpollfd,events[i].data.fd,3,0);
events[i].data.fd = -1;
fprintf(stdout," error 2 write %s\n",sReadBuf);
close(events[i].data.fd);
}
}
//fprintf(stdout,"%s %s\n",sWriteBuf,strerror(errno));
}
EpollSet(iEpollfd,events[i].data.fd,0,0);
}
}
}
iGetsocknum++;
}
}
int main(int argc,char **argv){
mydaemon();
InitListenSockt(PORT);
for ( int i=0;i<PIDNUM;i++)
{
forkpid[i] = fork();
if ( forkpid[i] ==-1 )
{
exit(-1);
}
if ( forkpid[i] == 0 )
{
Woker();
}
}
SetSigHandler(SIGINT,KillChild);
for ( int i=0;i<PIDNUM;i++ )
{
wait(NULL);
}
}
mydaemon.c
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
void mydaemon(){
pid_t pid;
pid= fork();
if ( pid > 0 )
{
/*父进程退出*/
exit(0);
}
/*设置进程组识别码方便接收组内进程的信号*/
setpgrp( );
/*创建会话,成为会话组长,摆脱控制终端,成为可以打开设备的进程*/
setsid( );
/*忽略挂起信号*/
signal( SIGHUP, SIG_IGN );
/*重新创建子进程,防止误打开终端设备,fork之后保证子进程不会是会话首进程。*/
pid = fork( ) ;
if ( pid > 0 )
{
exit( 0 );
}
/*设置进程掩码,去除继承自父进程的掩码设置*/
umask( 0 );
int i = -1;
//i=getdtablesize();
/*关闭无用的打开的文件描述符,先获取可打开的最大文件描述符,然后轮询关闭*/
for ( i;i>=0;i-- )
( void ) close( i );
}
lib.c
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/epoll.h>
#define DeBugLog() fprintf(stderr,"%s %d %d: %s\n",__FILE__,__LINE__,__func__,strerror(errno))
typedef void ( * sighandler_t) (int);
int iGLoop=1;
extern int Port;
void iLoopSet()
{
iGLoop = 0;
}
sighandler_t SetSigHandler(int sigtype,sighandler_t handler){
return signal(sigtype,handler);
}
void SetNoBlock(int fd,int type){
int iRet=0;
switch( type )
{
case 0:
iRet = fcntl(fd,F_SETFL,O_NONBLOCK);
break;
default:
iRet = fcntl(fd,F_SETFL,O_NONBLOCK);
break;
}
if ( iRet == -1 )
{
DeBugLog();
}
}
int GetSocket(int type){
int sockfd;
switch( type )
{
case 0 :
sockfd=socket(AF_INET,SOCK_STREAM,0);
break;
case 1:
break;
case 2:
default:
sockfd=socket(AF_INET,SOCK_STREAM,0);
break;
}
if ( sockfd < 0 )
DeBugLog();
return sockfd;
}
int Mybind(int fd,int type){
int iRet=0;
socklen_t socklen;
struct sockaddr_in stServ;
socklen = sizeof( stServ );
memset((char *)&stServ,0x00,sizeof(stServ));
switch( type )
{
case 0: stServ.sin_family = AF_INET;
break;
default:
break;
}
stServ.sin_addr.s_addr = INADDR_ANY;
stServ.sin_port = htons(Port);
if ( bind(fd,(struct sockaddr*)&stServ,socklen ) == -1 )
{
DeBugLog();
return -1;
}
}
void Mylisten(int fd,int listennum){
listen(fd,listennum);
}
int Setsockopt(int fd,int type )
{
int reuseaddr=1;
int iRet=0;
switch( type )
{
case 0:
iRet=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,(const void *) &reuseaddr, sizeof(int));
break;
case 1:
iRet=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,(const void *) &reuseaddr, sizeof(int));
break;
default:
iRet=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,(const void *) &reuseaddr, sizeof(int));
break;
}
if ( iRet == -1 )
{
DeBugLog();
}
return iRet;
}