zoukankan      html  css  js  c++  java
  • 多进程服务器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=='
    ')
    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
    ");
     30     while(1){
     31         clientaddr_len=sizeof(clientaddr);
     32         connfd=Accept(listenfd,(struct sockaddr *)&clientaddr,&clientaddr_len);
     33         printf("client ip: %s	port :%d
    ",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:
    ");
     28         Write(STDOUT_FILENO,buf,len);
     29     }
     30 
     31     Close(confd);
     32     return 0;
     33 }
  • 相关阅读:
    Python-装饰器进阶
    JavaScript-CasperJs使用教程
    Python-第三方库requests详解
    PHP-PHP程序员的技术成长规划(By黑夜路人)
    Bootstrap-学习系列
    CSS-常用媒体查询
    Git-随笔
    工具-各种开源
    PHP-PHP5.3及以上版本中检查json格式的方法
    VIM-技巧
  • 原文地址:https://www.cnblogs.com/General-up/p/5449729.html
Copyright © 2011-2022 走看看