Linux网络编程——tcp并发服务器(多进程)

http://blog.csdn.net/lianghe_work/article/details/46503895

一、tcp并发服务器概述

一个好的服务器,一般都是并发服务器(同一时刻可以响应多个客户端的请求)。并发服务器设计技术一般有:多进程服务器、多线程服务器、I/O复用服务器等。


二、多进程并发服务器

在 Linux 环境下多进程的应用很多,其中最主要的就是网络/客户服务器。多进程服务器是当客户有请求时,服务器用一个子进程来处理客户请求。父进程继续等待其它客户的请求。这种方法的优点是当客户有请求时,服务器能及时处理客户,特别是在客户服务器交互系统中。对于一个 TCP 服务器,客户与服务器的连接可能并不马上关闭,可能会等到客户提交某些数据后再关闭,这段时间服务器端的进程会阻塞,所以这时操作系统可能调度其它客户服务进程,这比起循环服务器大大提高了服务性能

发达

tcp多进程并发服务器

TCP 并发服务器的思想是每一个客户机的请求并不由服务器直接处理,而是由服务器创建一个子进程来处理。


tcp多进程并发服务器参考代码:

[csharp]  view plain  copy
  1. #include   
  2. #include   
  3. #include                          
  4. #include   
  5. #include   
  6. #include   
  7. #include       
  8.   
  9. /************************************************************************ 
  10. 函数名称:   void main(int argc, char *argv[]) 
  11. 函数功能:   主函数,用进程建立一个TCP Echo Server 
  12. 函数参数:   无 
  13. 函数返回:   无 
  14. ************************************************************************/  
  15. int main(int argc, char *argv[])  
  16. {  
  17.     unsigned short port = 8080;     // 本地端口   
  18.   
  19.     //1.创建tcp套接字  
  20.     int sockfd = socket(AF_INET, SOCK_STREAM, 0);     
  21.     if(sockfd < 0)  
  22.     {  
  23.         perror("socket");  
  24.         exit(-1);  
  25.     }  
  26.       
  27.     //配置本地网络信息  
  28.     struct sockaddr_in my_addr;  
  29.     bzero(&my_addr, sizeof(my_addr));     // 清空     
  30.     my_addr.sin_family = AF_INET;         // IPv4  
  31.     my_addr.sin_port   = htons(port);     // 端口  
  32.     my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // ip  
  33.       
  34.     //2.绑定  
  35.     int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));  
  36.     if( err_log != 0)  
  37.     {  
  38.         perror("binding");  
  39.         close(sockfd);        
  40.         exit(-1);  
  41.     }  
  42.       
  43.     //3.监听,套接字变被动  
  44.     err_log = listen(sockfd, 10);   
  45.     if(err_log != 0)  
  46.     {  
  47.         perror("listen");  
  48.         close(sockfd);        
  49.         exit(-1);  
  50.     }  
  51.       
  52.     while(1) //主进程 循环等待客户端的连接  
  53.     {  
  54.           
  55.         char cli_ip[INET_ADDRSTRLEN] = {0};  
  56.         struct sockaddr_in client_addr;  
  57.         socklen_t cliaddr_len = sizeof(client_addr);  
  58.           
  59.         // 取出客户端已完成的连接  
  60.         int connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);  
  61.         if(connfd < 0)  
  62.         {  
  63.             perror("accept");  
  64.             close(sockfd);  
  65.             exit(-1);  
  66.         }  
  67.           
  68.         pid_t pid = fork();  
  69.         if(pid < 0){  
  70.             perror("fork");  
  71.             _exit(-1);  
  72.         }else if(0 == pid){ //子进程 接收客户端的信息,并发还给客户端  
  73.             /*关闭不需要的套接字可节省系统资源, 
  74.               同时可避免父子进程共享这些套接字 
  75.               可能带来的不可预计的后果 
  76.             */  
  77.             close(sockfd);   // 关闭监听套接字,这个套接字是从父进程继承过来  
  78.           
  79.             char recv_buf[1024] = {0};  
  80.             int recv_len = 0;  
  81.               
  82.             // 打印客户端的 ip 和端口  
  83.             memset(cli_ip, 0, sizeof(cli_ip)); // 清空  
  84.             inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);  
  85.             printf("----------------------------------------------\n");  
  86.             printf("client ip=%s,port=%d\n", cli_ip,ntohs(client_addr.sin_port));  
  87.               
  88.             // 接收数据  
  89.             while( (recv_len = recv(connfd, recv_buf, sizeof(recv_buf), 0)) > 0 )  
  90.             {  
  91.                 printf("recv_buf: %s\n", recv_buf); // 打印数据  
  92.                 send(connfd, recv_buf, recv_len, 0); // 给客户端回数据  
  93.             }  
  94.               
  95.             printf("client_port %d closed!\n", ntohs(client_addr.sin_port));  
  96.             close(connfd);    //关闭已连接套接字  
  97.             exit(0);  
  98.               
  99.         }  
  100.         else if(pid > 0){    // 父进程  
  101.             close(connfd);    //关闭已连接套接字  
  102.         }  
  103.     }  
  104.       
  105.     close(sockfd);  
  106.       
  107.     return 0;  
  108. }  


运行结果:

你可能感兴趣的:(Linux网络编程)