TCP并发服务器

来源:互联网 发布:身高 知乎 编辑:程序博客网 时间:2024/06/04 22:16

服务器模型

在网络程序里面,一般来说都是许多客户对应一个服务器,为了处理客户的请求,对服务端的程序就提出了特殊的要求。目前最常用的服务器模型有:

1.循环服务器。服务器在同一时刻只能响应一个客户端的请求。

2.并发服务器。服务器在同一时刻可以响应多个客户端的请求。

前面介绍的为TCP和UDP循环服务器。

TCP并发服务器

并发服务器的思想是每一个客户机的请求并不由服务器直接处理,而是由服务器创建一个子进程处理。程序步骤如下:

socket(...);

bind(...);

listen(...);

while(1)

{

         accept(...);

         if(fork(..) == 0)

         {

               process();

               close();

               exit();

          }

          close();

}

服务器端程序实例,tcp_server_fork.c如下:

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define MY_PORT 3333

int main(int argc ,char **argv)
{
 int listen_fd,accept_fd;
 struct sockaddr_in     client_addr;
 int n;
 int nbytes;
 
  if((listen_fd=socket(AF_INET,SOCK_STREAM,0))<0)
   {
         printf("Socket Error:%s/n/a",strerror(errno));
         exit(1);
   }
 
  bzero(&client_addr,sizeof(struct sockaddr_in));
  client_addr.sin_family=AF_INET;
  client_addr.sin_port=htons(MY_PORT);
  client_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  n=1;
 
  /* 如果服务器终止后,服务器可以第二次快速启动而不用等待一段时间  */
  setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int));
  if(bind(listen_fd,(struct sockaddr *)&client_addr,sizeof(client_addr))<0)
   {
         printf("Bind Error:%s/n/a",strerror(errno));
         exit(1);
   }
 
   listen(listen_fd,5);
   
   while(1)
   {
     accept_fd=accept(listen_fd,NULL,NULL);
     if((accept_fd<0)&&(errno==EINTR))
            continue;
     else if(accept_fd<0)
      {
          printf("Accept Error:%s/n/a",strerror(errno));
          continue;
      }
    if((n=fork())==0)
     {
          /* 子进程处理客户端的连接 */
          char buffer[1024];

          if((nbytes=read(accept_fd,buffer,1024))==-1)
   {
    fprintf(stderr,"Read Error:%s/n",strerror(errno));
    exit(1);
   }   
   buffer[nbytes]='/0';
   printf("Server received %s/n",buffer);
          
          close(listen_fd);
          close(accept_fd);
          exit(0);
     }
     else
      close(accept_fd);
 }
}

 

 

 

 

 

 

 

 

 

原创粉丝点击