Linux网络编程服务器模型选择之循环服务器
来源:互联网 发布:淘宝企业店开店流程 编辑:程序博客网 时间:2024/05/29 03:03
转载:http://www.cnblogs.com/lizhenghn/p/3617608.html
在网络程序里面,通常都是一个服务器处理多个客户机,为了出个多个客户机的请求,服务器端的程序有不同的处理方式。本节开始介绍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 1234510 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 }
1 /** UDP循环服务器--client端程序**/ 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 1234510 int main(int argc, char *argv[])11 {12 int s; //服务器套接字文件描述符13 struct sockaddr_in server; //本地地址14 time_t now; 15 char buff[BUFFLEN]; 16 int n = 0; 17 int len = 0; //地址长度18 19 //建立UDP套接字20 s = socket(AF_INET, SOCK_DGRAM, 0);21 22 //初始化地址接 23 memset(&server, 0, sizeof(server));24 server.sin_family = AF_INET;//AF_INET协议族25 server.sin_addr.s_addr = htonl(INADDR_ANY);//任意本地地址26 server.sin_port = htons(SERVER_PORT);//服务器端口27 28 memset(buff, 0, BUFFLEN); 29 strcpy(buff, "TIME"); 30 //发送数据31 sendto(s, buff, strlen(buff), 0, (struct sockaddr*)&server, sizeof(server));32 memset(buff, 0, BUFFLEN);33 //接收数据34 len = sizeof(server);35 n = recvfrom(s, buff, BUFFLEN, 0, (struct sockaddr*)&server, &len);36 if(n >0)37 printf("TIME:%s",buff); 38 39 close(s);40 41 return 0; 42 }
TCP循环服务器
1 /** TCP循环服务器--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 1234610 #define BACKLOG 511 int main(int argc, char *argv[])12 {13 int s_s, s_c; /*服务器套接字文件描述符*/14 struct sockaddr_in local, from; /*本地地址*/15 time_t now; 16 char buff[BUFFLEN];17 int n = 0;18 int len = sizeof(from);19 20 /*建立TCP套接字*/21 s_s = socket(AF_INET, SOCK_STREAM, 0);22 23 /*初始化地址*/24 memset(&local, 0, sizeof(local));25 local.sin_family = AF_INET;/*AF_INET协议族*/26 local.sin_addr.s_addr = htonl(INADDR_ANY);/*任意本地地址*/27 local.sin_port = htons(SERVER_PORT);/*服务器端口*/28 29 /*将套接字文件描述符绑定到本地地址和端口*/30 int err = bind(s_s, (struct sockaddr*)&local, sizeof(local));31 err = listen(s_s, BACKLOG);/*侦听*/32 33 /*主处理过程*/34 while(1)35 {36 /*接收客户端连接*/37 s_c = accept(s_s, (struct sockaddr*)&from, &len);38 memset(buff, 0, BUFFLEN);39 n = recv(s_c, buff, BUFFLEN,0);/*接收发送方数据*/40 if(n > 0 && !strncmp(buff, "TIME", 4))/*判断是否合法接收数据*/41 {42 memset(buff, 0, BUFFLEN);43 now = time(NULL);44 sprintf(buff, "%24s\r\n",ctime(&now));45 send(s_c, buff, strlen(buff),0);/*发送数据*/46 }47 close(s_c);48 }49 close(s_s);50 51 return 0; 52 }
/**TCP循环服务器--client端程序**/#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <stdio.h>#define BUFFLEN 1024#define SERVER_PORT 12346int main(int argc, char *argv[]){ int s; /*服务器套接字文件描述符*/ struct sockaddr_in server; /*本地地址*/ char buff[BUFFLEN]; int n = 0; /*建立TCP套接字*/ s = socket(AF_INET, SOCK_STREAM, 0); /*初始化地址*/ memset(&server, 0, sizeof(server)); server.sin_family = AF_INET;/*AF_INET协议族*/ server.sin_addr.s_addr = htonl(INADDR_ANY);/*任意本地地址*/ server.sin_port = htons(SERVER_PORT);/*服务器端口*/ /*连接服务器*/ int err = connect(s, (struct sockaddr*)&server,sizeof(server)); memset(buff, 0, BUFFLEN); strcpy(buff, "TIME"); /*发送数据*/ send(s, buff, strlen(buff), 0); memset(buff, 0, BUFFLEN); /*接收数据*/ n = recv(s, buff, BUFFLEN, 0); if(n >0){ printf("TIME:%s",buff); } close(s); return 0; }
两者返回给客户端的的输出都是一样的,比如:TIME:Sat Mar 22 15:26:25 2014
循环服务器的介绍就到这里。接下来介绍并发服务器模型。
阅读全文
0 0
- Linux网络编程服务器模型选择之循环服务器
- Linux网络编程服务器模型选择之IO复用循环并发服务器
- Linux网络编程服务器模型选择之并发服务器(上)
- Linux网络编程服务器模型选择之并发服务器(下)
- Linux网络编程之循环服务器
- Linux网络编程之循环服务器
- Linux网络编程之循环服务器
- Linux网络编程--服务器模型
- linux 网络编程----服务器模型
- Linux网络编程--服务器模型
- linux网络编程-服务器模型
- socket网络编程 服务器模型选择
- unix网络编程--服务器模型选择
- Linux网络编程之循环服务器(转)
- Linux网络编程之I/O复用循环服务器
- Linux网络编程之I/O复用循环服务器
- Linux网络编程之I/O复用循环服务器
- [Linux网络编程] 循环服务器的实现
- Java反射理解
- 阿里巴巴荣获年度最佳BCM创新实践奖
- 大数据产品推荐:金蜂巢大数据集成与脱敏系统
- java8-静态方法引用
- 数据结构实验之链表一:顺序建立链表
- Linux网络编程服务器模型选择之循环服务器
- Packagist 镜像使用方法
- 【10月新版】Aspose.Pdf 10月新版V17.10发布 | 附下载
- cinder的配置和子服务
- LinkedHashMap和HashMap的比较使用
- 前端基础知识总结
- Google开源了Abseil,为C++和Python开发提供支持
- shader内置变量和函数
- 吴恩达第5周答案 Neural Networks: Learning 答案