Chinaunix首页 | 论坛 | 博客
  • 博客访问: 321492
  • 博文数量: 64
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1972
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-31 21:53
个人简介

文明之精神,野蛮之体魄。

文章分类
文章存档

2015年(4)

2013年(60)

我的朋友

分类: LINUX

2013-08-30 15:43:25

//superd.c
  1 #define _USE_BSD
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14 #include
 15 #include
 16
 17 #define UDP_SERV 0
 18 #define TCP_SERV 1
 19 #define NOSOCK -1
 20
 21 struct service{
 22     char *sv_name;
 23     char sv_useTCP;
 24     int sv_sock;
 25     int (*sv_func)(int);
 26 };
 27
 28 void TCPechod(int),TCPchargend(int),TCPdaytimed(int),TCPtimed(int);
 29 int passiveTCP(const char *service,int qlen);//见上篇博文"多线程echo服务器的实现",http://blog.chinaunix.net/uid-26345906-id-3871257.html
 30 int passiveUDP(const char *service);
 31 int errexit(const char *format,...);
 32 void doTCP(struct service *psv);
 33 void reaper(int sig);
 34
 35 struct service svent[] =
 36 {
 37     {"echo",TCP_SERV,NOSOCK,TCPechod},
 38     {"chargen",TCP_SERV,NOSOCK,TCPchargend},
 39     {"daytime",TCP_SERV,NOSOCK,TCPdaytimed},
 40     {"time",TCP_SERV,NOSOCK,TCPtimed},
 41     {0,0,0,0},
 42 };
 43 #ifndef MAX
 44 #define MAX(x,y) (x > y) ? x : y
 45 #endif
 46 #define QLEN 32
 47 #define LINELEN 128
 48
 49 extern unsigned short portbase;
 50
 51 int main(int argc,char **argv)
 52 {
 53     struct service *psv,*fd2sv[NOFILE];
 54     int fd,nfds;
 55     fd_set afds,rfds;
 56
 57     switch(argc){
 58         case 1:
 59             break;
 60         case 2:
 61             portbase = (unsigned short)atoi(argv[1]);
 62             break;
 63         default:
 64             errexit("usage: superd[portbase]\n");
 65     }
 66     nfds = 0;
 67     FD_ZERO(&afds);
 68     for(psv = &svent[0]; psv->sv_name; ++psv){
 69         if(psv->sv_useTCP)
 70             psv->sv_sock = passiveTCP(psv->sv_name,QLEN);
 71         else
 72             psv->sv_sock = passiveUDP(psv->sv_name);
 73         fd2sv[psv->sv_sock] = psv;
 74         nfds = MAX(psv->sv_sock + 1,nfds);
 75         FD_SET(psv->sv_sock,&afds);
 76     }
 77     signal(SIGCHLD,reaper);
 78     while(1){
 79         memcpy(&rfds,&afds,sizeof(rfds));
 80         if(select(nfds,&rfds,(fd_set*)0,(fd_set*)0,(struct timeval*)0) < 0){
 81             if(errno == EINTR)
 82                 continue;
 83             errexit("select error: %s\n",strerror(errno));
 84         }
 85         for(fd = 0; fd < nfds; ++fd)
 86             if(FD_ISSET(fd,&rfds)){
 87                 psv = fd2sv[fd];
 88                 if(psv->sv_useTCP)
 89                     doTCP(psv);
 90                 else
 91                     psv->sv_func(psv->sv_sock);
 92             }
 93     }
 94 }
 95 void doTCP(struct service *psv)
 96 {
 97     struct sockaddr_in fsin;
 98     unsigned int alen;
 99     int fd,ssock;
100
101     alen = sizeof(fsin);
102     ssock = accept(psv->sv_sock,(struct sockaddr*)&fsin,&alen);
103     if(ssock < 0)
104         errexit("accept: %s\n",strerror(errno));
105     switch(fork()){
106         case 0:
107             break;
108         case -1:
109             errexit("fork: %s\n",strerror(errno));
110         default:
111             close(ssock);
112             return;
113     }
114     for(fd = NOFILE; fd >= 0; --fd)
115         if(fd != ssock)
116             close(fd);
117     psv->sv_func(ssock);
118     exit(0);
119 }
120 void reaper(int sig)
121 {
122     int status;
123     while(wait3(&status,WNOHANG,(struct rusage*)0) >= 0)
124         ;
125 }

//sv_funcs.c包含了处理各个服务的函数的代码
 1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7
  8 #define BUFSIZE 4096
  9
 10 errexit(const char *format,...);
 11
 12 void TCPechod(int fd)
 13 {
 14     char buf[BUFSIZE];
 15     int cc;
 16
 17     while(cc = read(fd,buf,sizeof(buf))){
 18         if(cc < 0)
 19             errexit("echo read: %s\n",strerror(errno));
 20         if(write(fd,buf,cc) < 0)
 21             errexit("echo write: %s\n",strerror(errno));
 22     }
 23 }
 24
 25 #define LINELEN 72
 26 void TCPchargend(int fd)
 27 {
 28     char c,buf[LINELEN + 2];
 29     c = ' ';
 30     buf[LINELEN] = '\r';
 31     buf[LINELEN + 1] = '\n';
 32     while(1){
 33         int i;
 34         for(i = 0; i < LINELEN; ++i){
 35             buf[i] = c++;
 36             if(c > '~')
 37                 c = ' ';
 38         }
 39         if(write(fd,buf,LINELEN + 2) < 0)
 40             break;
 41     }
 42 }
 43
 44 void TCPdaytimed(int fd)
 45 {
 46     char buf[LINELEN],*ctime();
 47     time_t now;
 48     time(&now);
 49     sprintf(buf,"%s",ctime(&now));
 50     write(fd,buf,strlen(buf));
 51 }
 52 #define UNIXEPOCH 2208988800UL
 53 void TCPtimed(int fd)
 54 {
 55     time_t now;
 56     time(&now);
 57     now = htonl((unsigned long)(now + UNIXEPOCH));
 58     write(fd,(char *)&now,sizeof(now));
 59 }



阅读(1935) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~