你的位置:首页 > 操作系统

[操作系统]多进程服务器Demo


  今天实现的这个服务器程序加入了对多个客户端同时请求处理的实现,服务器端通过对每次监听到的客户端程序新建一个子进程,进行相关的处理,将从客户端传来的字符串数据,转化为大写的字符串序列,然重新写回到connfd;另一方面,客户端通过在标准输入里获取客户输入到的字符串序列,传送到connfd,再从connfd读取经服务器处理过的字符串序列打印到标准输出上。

  同时,加上了对某些socket原语函数的封装处理,主要封装了对出错的处理机制,基本原语函数都以相应大写首个字符的命名表示,定义在“wrap.c”和“wrap.h”文件中。

wrap.h

 1 /* wrap.h */ 2 #ifndef __WRAP_H_ 3 #define __WRAP_H_ 4  5 void perr_exit(const char *s); 6 int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr); 7 void Bind(int fd, const struct sockaddr *sa, socklen_t salen); 8 void Connect(int fd, const struct sockaddr *sa, socklen_t salen); 9 void Listen(int fd, int backlog); 10 int Socket(int family, int type, int protocol); 11 ssize_t Read(int fd, void *ptr, size_t nbytes); 12 ssize_t Write(int fd, const void *ptr, size_t nbytes); 13 void Close(int fd); 14 ssize_t Readn(int fd, void *vptr, size_t n); 15 ssize_t Writen(int fd, const void *vptr, size_t n); 16 static ssize_t my_read(int fd, char *ptr); 17 ssize_t Readline(int fd, void *vptr, size_t maxlen); 18 19 #endif

 

wrap.c

 1 /*wrap.c */ 2 #include<stdlib.h> 3 #include<errno.h> 4 #include<sys/socket.h> 5  6 void perr_exit(const char* s) 7 { 8   perror(s); 9   exit(1); 10 } 11 12 int Accept(int fd,struct sockaddr *sa,socklen_t *salenptr) 13 { 14   int n; 15 again: 16   if((n=accept(fd,sa,salenptr))<0){ 17     if((errno==ECONNABORTED)||(errno==EINTR)) 18       goto again; 19     else 20       perr_exit("accept error"); 21   } 22   return n; 23 } 24 25 void Bind(int fd,const struct sockaddr *sa,socklen_t salen) 26 { 27   if(bind(fd,sa,salen)<0) 28     perr_exit("bind error"); 29 } 30 31 void Connect(int fd,const struct sockaddr *sa,socklen_t salen) 32 { 33   if(connect(fd,sa,salen)<0) 34     perr_exit("connect error"); 35 } 36 37 void Listen(int fd,int backlog) 38 { 39   if(listen(fd,backlog)<0) 40     perr_exit("listen error"); 41 } 42 43 int Socket(int family,int type,int protocol) 44 { 45   int n; 46   if((n=socket(family,type,protocol))<0) 47     perr_exit("socket error"); 48   return n; 49 } 50 51 ssize_t Read(int fd,void *ptr,size_t nbytes) 52 { 53   ssize_t n; 54 again: 55   if((n=read(fd,ptr,nbytes))==-1){ 56     if(errno==EINTR) 57       goto again; 58     else 59       return -1; 60   } 61   return n; 62 } 63 64 ssize_t Write(int fd,const void *ptr,size_t nbytes) 65 {  66   ssize_t n; 67 again: 68   if((n=write(fd,ptr,nbytes))==-1){ 69     if(errno==EINTR) 70       goto again; 71     else 72       return -1; 73   } 74   return n; 75 } 76 77 void Close(int fd) 78 {  79   if(close(fd)==-1) 80     perr_exit("close error"); 81 } 82 83 ssize_t Readn(int fd,void *vptr,ssize_t n) 84 {  85   size_t nleft; 86   ssize_t nread; 87   char *ptr; 88   ptr=vptr; 89   nleft=n; 90   while(nleft>0){ 91     if((nread=read(fd,ptr,nleft))<0){ 92       if(errno==EINTR) 93         nread=0; 94       else 95         return -1; 96     }else if(nread==0) 97       break; 98     nleft-=nread; 99     ptr+=nread;100   }101   return n-nleft;102 }103 104 105 ssize_t Writen(int fd,const void *vptr,size_t n)106 {107   size_t nleft;108   ssize_t nwritten;109   const char* ptr;110   ptr=vptr;111   nleft=n;112   while(nleft>0){113     if(nwritten=write(fd,ptr,nleft)<=0){114       if(nwritten<0&&errno==EINTR)115         nwritten=0;116       else117         return -1;118     }119     nleft-=nwritten;120     ptr+=nwritten;121   }122   return n;123 }124 125 static ssize_t my_read(int fd,char* ptr)126 {127   static int read_cnt;128   static char *read_ptr;129   static char read_buf[100];130   if(read_cnt<=0){131 again:132     if((read_cnt=read(fd,read_buf,sizeof(read_buf)))<0){133       if(errno==EINTR)134         goto again;135       else136         return -1;137     }else if(read_cnt==0)138       return 0;139     read_ptr=read_buf;140   }141   read_cnt--;142   *ptr=*read_ptr++;143   return 1;144 }145 146 ssize_t Readline(int fd,void *vptr,size_t maxlen)147 {148   ssize_t n,rc;149   char c,*ptr;150   ptr=vptr;151   for(n=1;n<maxlen;n++){152     if((rc=my_read(fd,&c))==1){153       *ptr++=c;154       if(c=='\n')155         break;156     }else if(rc==0){157       *ptr=0;158       return n-1;159     }else160       return -1;161   }162   *ptr=0;163   return n;164 }165 

 

服务器端:

 1 #include<stdlib.h> 2 #include<stdio.h> 3 #include<unistd.h> 4 #include<string.h> 5 #include<netinet/in.h> 6 #include<sys/types.h> 7 #include<sys/socket.h> 8 #include<arpa/inet.h> 9 #include "wrap.c" 10 #define SERVER_PORT 8000 11 #define BUFSIZE 80 12 int main(int argc,char* argv[]) 13 { 14   struct sockaddr_in serveraddr,clientaddr; 15   int listenfd,connfd,len,clientaddr_len,i; 16   char buf[BUFSIZE]; 17   char str[BUFSIZE]; 18   pid_t pid; 19   listenfd=Socket(AF_INET,SOCK_STREAM,0); 20 21   bzero(&serveraddr,sizeof(serveraddr)); 22   serveraddr.sin_family=AF_INET; 23   serveraddr.sin_addr.s_addr=htonl(INADDR_ANY); 24   serveraddr.sin_port=htons(SERVER_PORT); 25 26   Bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)); 27 28   Listen(listenfd,128); 29   printf("waiting for connecting\n"); 30   while(1){ 31     clientaddr_len=sizeof(clientaddr); 32     connfd=Accept(listenfd,(struct sockaddr *)&clientaddr,&clientaddr_len); 33     printf("client ip: %s\tport :%d\n",inet_ntop(AF_INET,&clientaddr.sin_addr.s_addr,str,sizeof(str)),ntohs(clientaddr.sin_port)); 34     pid=fork(); 35     if(pid==0){ 36         Close(listenfd); 37         while(1){ 38           len=Read(connfd,buf,sizeof(buf)); 39           for(i=0;i<len;i++) 40             buf[i]=toupper(buf[i]); 41           Write(connfd,buf,len); 42         } 43         Close(connfd); 44         return 0; 45     }else if(pid>0){ 46         Close(connfd); 47     } 48     else{ 49       //error deal 50     } 51   } 52 // Close(listenfd); 53   return 0; 54 }

客户端:

 1 #include<stdlib.h> 2 #include<stdio.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<netinet/in.h> 6 #include<sys/socket.h> 7 #include<unistd.h> 8 #include "wrap.c" 9 #define SERVER_PORT 8000 10 #define BUFSIZE 80 11 int main(int argc,char* argv[]) 12 { 13   int confd,len; 14   struct sockaddr_in serveraddr; 15   confd=Socket(AF_INET,SOCK_STREAM,0); 16   char buf[BUFSIZE]; 17 18   bzero(&serveraddr,sizeof(serveraddr)); 19   serveraddr.sin_family=AF_INET; 20   inet_pton(AF_INET,"127.0.0.1",&serveraddr.sin_addr.s_addr); 21   serveraddr.sin_port=htons(SERVER_PORT); 22 23   Connect(confd,(struct sockaddr*)&serveraddr,sizeof(serveraddr)); 24   while(fgets(buf,sizeof(buf),stdin)){ 25     Write(confd,buf,strlen(buf)); 26     len=Read(confd,buf,BUFSIZE); 27     printf("the result from server:\n"); 28     Write(STDOUT_FILENO,buf,len); 29   } 30 31   Close(confd); 32   return 0; 33 }