Zirconi

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

尝试了一下在主进程只fork,子进程accept的结构,由于是测试用的小例子所以限定了用户数量为5个。

 

 

  1 #include <unistd.h>
  2 #include <pthread.h>
  3 #include <sys/wait.h>
  4 #include <sys/socket.h>
  5 #include <netinet/in.h>
  6 #include <arpa/inet.h>
  7 #include <signal.h>
  8 #include <errno.h>
  9 #include <stdlib.h>
 10 #include <stdio.h>
 11 #include <string.h>
 12 
 13 #define USERNUM 5
 14 #define SERVPORT 4322
 15 
 16 void
 17 rep_err(const char *msg)
 18 {
 19     fprintf(stderr, "%s\n", msg);
 20     perror("ECHOSERVER");
 21     exit(-1);
 22 }
 23 
 24 
 25 void
 26 dealchild(int signo)
 27 {
 28     pid_t pid;
 29     int   stat;
 30     while((pid = waitpid(-1, &stat, WNOHANG)) > 0);
 31         printf("Process %u is TERMINAL\n", pid);
 32     return;
 33 }
 34 
 35 void dofork(int);
 36 
 37 pthread_mutex_t MUTEX = PTHREAD_MUTEX_INITIALIZER;
 38 
 39 int
 40 main(int argc, char *argv[])
 41 {
 42     int               listenfd, err, i;
 43     pid_t             pid;
 44     struct sockaddr_in servaddr;
 45 
 46     if(signal(SIGCHLD, dealchild) == SIG_ERR)
 47         rep_err("SIGNAL");
 48 
 49     if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
 50         rep_err("SOCKET");
 51 
 52     memset(&servaddr, 0, sizeof(servaddr));
 53     servaddr.sin_family = AF_INET;
 54     servaddr.sin_port = htons(SERVPORT);
 55     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 56 
 57     if((err = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) < 0)
 58         rep_err("BIND");
 59 
 60     if((err = listen(listenfd, 128)) < 0)
 61         rep_err("LISTEN");
 62 
 63     for(i = 0; i < USERNUM; ++i)
 64     {
 65         if((pid = fork()) == 0)
 66         {
 67             dofork(listenfd);
 68         }
 69         else if(pid > 0)
 70         {}
 71         else
 72             rep_err("FORK");
 73     }
 74 
 75     pause();
 76 
 77     exit(0);
 78 }
 79 
 80 void
 81 dofork(int fd)
 82 {
 83     int                connfd, n;
 84     char               buffer[256];
 85     char               buf[128];
 86     struct sockaddr_in cli;
 87     socklen_t          clilen;
 88 
 89     clilen = sizeof(cli);
 90     pthread_mutex_lock(&MUTEX);
 91     if((connfd = accept(fd, (struct sockaddr *)&cli, &clilen)) <= 0)
 92         rep_err("ACCEPT");
 93     pthread_mutex_unlock(&MUTEX);
 94 
 95     snprintf(buffer, 256,
 96             "HELLO %s , FROM PORT : %d\n", 
 97             inet_ntop(AF_INET, &cli.sin_addr, buf, 128), 
 98             ntohs(cli.sin_port));
 99 
100     write(connfd, buffer, strlen(buffer));
101 
102         for(;;)
103         {
104 again:
105             if((n = read(connfd, buffer, 256)) < 0)
106             {
107                 if(errno == EINTR)
108                     goto again;
109                 else
110                     rep_err("READ");
111             }
112             write(connfd, buffer, n);
113         }
114 }

 

posted on 2013-04-16 16:45  Zirconi  阅读(299)  评论(0编辑  收藏  举报