linux多进程并发服务模型

Linux多进程并发的服务器,其原理是:
1、Linux下fork创建新进程,子进程会复制父进程资源,即子进程会复制父进程中文件、文件系统、虚拟内存等结构。
2、close()函数关闭描述符,只是将访问计数值减1,当描述符的计数值为0时,描述符才会真正关闭。
所以Linux多进程并发服务器的工作流程是这样的:
父进程负责接收处理客户请求,其后调用fork建立子进程,此时监听与已连接描述符相关连的文件表象的访问计数值均加1,子进程调用close函数关闭监听描述符,其后处理用户请求。父进程继续等待接收处理客户请求。
 
示例程序建立一个多进程并发服务器程序和一个客户端程序,服务器程序将客户端发过来的字符串中的小写字母全部转化为大学字母后发回客户端。
 
服务器程序代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>

  9. #define MAXDATASIZE 1024
  10. #define PORT 1111
  11. #define BACKLOG 5


  12. void process(int connectfd){
  13.     char buf[MAXDATASIZE];
  14.     int num=0;
  15.     while(0<(num=read(connectfd,buf,sizeof(buf)))){
  16.         buf[num]='\0';
  17.         if(0==strcmp(buf,"bye"))
  18.             break;
  19.         int i=0;
  20.         puts(buf);
  21.         while(buf[i]){
  22.             if(buf[i]>='a'&&buf[i]<='z')
  23.                 buf[i]=buf[i]-'a'+'A';
  24.             i++;
  25.         }
  26.         write(connectfd,buf,strlen(buf));
  27.     }
  28.     close(connectfd);
  29. }

  30. int main(){
  31.     int listenfd,connectfd;
  32.     struct sockaddr_in server;
  33.     struct sockaddr_in client;
  34.     int len;
  35.     pid_t pid;

  36.     if(-1==(listenfd=socket(AF_INET,SOCK_STREAM,0))){
  37.         perror("create socket error");
  38.         exit(1);
  39.     }

  40.     int opt=SO_REUSEADDR;
  41.     setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

  42.     bzero(&server,sizeof(server));

  43.     server.sin_family=AF_INET;
  44.     server.sin_port=htons(PORT);
  45.     server.sin_addr.s_addr=htonl(INADDR_ANY);

  46.     if(-1==bind(listenfd,(struct sockaddr *)&server,sizeof(struct sockaddr ))){
  47.         perror("bind error\n");
  48.         exit(1);
  49.     }

  50.     if(-1==listen(listenfd,BACKLOG)){
  51.         perror("listen error\n");
  52.         exit(1);
  53.     }

  54.     len=sizeof(client);

  55.     while(1){
  56.         if(-1==(connectfd=accept(listenfd,(struct sockaddr *)&client,&len))){
  57.             perror("connect error\n");
  58.             exit(1);
  59.         }

  60.         if((pid=fork())<0){
  61.             perror("fork error\n");
  62.             exit(1);
  63.         }
  64.         else if(0==pid){
  65.             close(listenfd);
  66.             printf("Got a connection from %s. \n",inet_ntoa(client.sin_addr));
  67.             process(connectfd);
  68.             exit(0);
  69.         }
  70.     }
  71.     close(listenfd);
  72.     return 0;
  73. }

 

客户端代码:

 

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <netdb.h>

  9. #define PORT 1111
  10. #define MAXDATASIZE 1024


  11. int main(int argc,char **argv){
  12.     int sockfd;
  13.     char buf[MAXDATASIZE];
  14.     struct hostent *he;
  15.     struct sockaddr_in server;
  16.     if(2>argc){
  17.         fprintf(stderr,"Usage: %s <host>\n",argv[0]);
  18.         exit(1);
  19.     }

  20.     if(NULL==(he=gethostbyname(argv[1]))){
  21.         perror("gethostbyname error\n");
  22.         exit(1);
  23.     }

  24.     if(-1==(sockfd=socket(AF_INET,SOCK_STREAM,0))){
  25.         perror("socket error\n");
  26.         exit(1);
  27.     }

  28.     bzero(&server,sizeof(server));
  29.     server.sin_family=AF_INET;
  30.     server.sin_port=htons(PORT);
  31.     server.sin_addr = *((struct in_addr*)he->h_addr);
  32.     if(-1==connect(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr))){
  33.         perror("connect error\n");
  34.         exit(1);
  35.     }

  36.     while(1){
  37.         gets(buf);
  38.         write(sockfd,buf,strlen(buf));
  39.         printf("send %s to server\n",buf);
  40.         int num=read(sockfd,buf,sizeof(buf));
  41.         buf[num]='\0';
  42.         puts(buf);
  43.     }
  44.     close(sockfd);
  45.     return 0;
  46. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值