在网络程序里面,通常都是一个服务器处理多个客户机,为了出个多个客户机的请求,服务器端的程序有不同的处理方式。本节开始介绍Linux下套接字编程的服务器模型选择,主要包括循环服务器模型、并发服务器模型、IO复用服务器模型等,这也是我们常见的几种网络服务器模型。其中基本可以分为两大类,

1. 循环服务器:循环服务器在同一时刻只能响应一个客户端的请求,是比较简单的一种模型;

2. 并发服务器:并发服务器在同一时刻可以响应多个客户端的请求,这里面又有很多分类,接下来会逐步介绍;

循环服务器模型

     循环服务器是指对于客户端的请求和连接,服务器逐个进行处理,处理完一个连接后再处理下一个连接,属于串行处理方式,结构比较简单。该模型的算法过程如下:

/* UDP循环服务器模型 */ 
 
socket(); 
 
bind(); 
 
while(true)
{
   recvfrom(); 
 
   process(); 
 
   sendto(); 
} 

close();
/* TCP循环服务器模型 */ 
 
socket(); 
 
bind(); 
 
listen(); 
 
while(true) 
{ 
 
    accept(); 
 
    while(true) 
    { 
        recv(); 
 
        process(); 
 
        send(); 
    } 
 
    close(); 
}

从上面的的流程可以看出,TCP循环服务器比UDP循环服务器多了一个accept的过程,这也是TCP和UDP套接字编程的主要区别。TCP服务器在accept出等待客户端的到来,因为accept函数是阻塞的,因此TCP服务器会在此等待(对accept函数的不同处理是区分各类服务器的一个重要参考依据)。相应地,UDP会在recvfrom阻塞,并等待客户端的连接。

一个循环服务器的例子

下面给出一个简单的循环服务器样子,模拟服务器对外提供时间服务器,等待客户端到来,并返回给客户端服务器的当前时间。

UDP循环服务器

 1 /** UDP循环服务器--server端程序**/
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <netinet/in.h>
 5 #include <time.h>
 6 #include <string.h>
 7 #include <stdio.h>
 8 #define BUFFLEN 1024
 9 #define SERVER_PORT 12345
10 int main(int argc, char *argv[])
11 {
12     int s;    //服务器套接字文件描述符
13     struct sockaddr_in local, to;    //本地地址
14     time_t now;        //时间
15     char buff[BUFFLEN];//收发数据缓冲区
16     int n = 0;
17     int len = sizeof(to);
18     
19     //建立UDP套接字
20     s = socket(AF_INET, SOCK_DGRAM, 0);
21     
22     //初始化地址
23     memset(&local, 0, sizeof(local));
24     local.sin_family = AF_INET;//AF_INET协议族
25     local.sin_addr.s_addr = htonl(INADDR_ANY);//任意本地地址
26     local.sin_port = htons(SERVER_PORT);//服务器端口
27     
28     //将套接字文件描述符绑定到本地地址和端口
29     int err = bind(s, (struct sockaddr*)&local, sizeof(local));
30     
31     //主处理过程
32     while(1)
33     {
34         memset(buff, 0, BUFFLEN);
35         n = recvfrom(s, buff, BUFFLEN,0,(struct sockaddr*)&to, &len);//接收发送方数据
36         if(n > 0 && !strncmp(buff, "TIME", 4))//判断是否合法接收数据
37         {
38             printf("Get One Client Connect\n");
39             memset(buff, 0, BUFFLEN);
40             now = time(NULL);
41             sprintf(buff, "%24s\r\n",ctime(&now));
42             sendto(s, buff, strlen(buff),0, (struct sockaddr*)&to, len);//发送数据
43         }
44     }
45     close(s);
46     
47     return 0;        
48 }
View Code

相关文章:

  • 2019-02-22
  • 2021-11-05
  • 2021-10-23
  • 2021-09-12
  • 2021-11-14
  • 2021-12-07
  • 2021-12-10
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-16
  • 2021-12-26
  • 2021-12-16
相关资源
相似解决方案