多進程服務器Demo

多進程服務器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             else
117                 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             else
136                 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         }else
160             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 }

 

posted @ 2016-04-30 23:25 General_up 閱讀(...) 評論(...) 編輯 收藏
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章