多进程的网络服务的一般模型
来源:互联网 发布:杨辉三角c语言程序六行 编辑:程序博客网 时间:2024/04/30 21:32
前述:多进程网络服务模式其实是基于Linux系统提供的父子进程的关系为多用户提供并发服务,是比较受大众喜爱的并发服务技术,其基本的服务理念是来一个客户,就启动一个服务进程!
多进程网络服务的实现原理:
第一步:>主服务在端进行绑定监听,同时设置被绑定的地址与端口是可重用的(因为可能会有多个进程要在同一个端口进行监听),启动监听;
第二步:>若当前有新连接到来,就启动一个子进程与其交互,服务结束后子进程自动退出
多进程网络服务的流程图如下示:
多进程网络服务的优点: 方法通用
多进程网络服务的缺点:
1> 每次启动并关闭子进程会带来很大的开销,在大用户量并发的前提下,会产生不小的负担;
2> 父子进程间的数据共享,同步等实现上有一定的困难;
无论如何,该模式在实际的商用环境中是一种可选的模式!!!!
以下是一个该模式的简单实现:
该示例是服务器处理来自客户端的请求:
服务器端的代码如下:
#include "../unp.h"//子进程处理通信过程void handler(int sock){ int sockconn = sock; //得到客户端的套接字 char sendbuf[100]; Oper op; int result; while(1) { int res = recv(sockconn, (char *)&op, sizeof(op), 0); //接收客户的消息 if(res == -1){ perror("recv"); } //对客户端的服务请求进行处理 if(op.oper == ADD){ //得到两数的和 result = op.op1 + op.op2; }else if(op.oper == SUB){ //得到两数的差 result = op.op1 - op.op2; }else if(op.oper == MUL){ //得到两个数的乘积 result = op.op1 * op.op2; }else if(op.oper == DIV){ //两个数的除 result = op.op1 / op.op2; }else if(op.oper == QUIT){ //客户端发出退出服务请求 struct sockaddr_in addrcli; socklen_t addrlen = sizeof(struct sockaddr); //客户端的地址结构大小 getpeername(sockconn, (struct sockaddr*)&addrcli, &addrlen); //得到对端即客户端的端口号(本例中是由系统自动分配的) printf("client[%d] quit.\n", addrcli.sin_port); break; } send(sockconn, (char *)&result, sizeof(int), 0); //将服务后得到的结果返回给客户端 }}int main(int ac, char *av[]){ int sockser = socket(AF_INET, SOCK_STREAM, 0); //得到服务器端的套接字 if(sockser == -1){ perror("socket"); } struct sockaddr_in addrser, addrcli; //服务器或客户端的地址结构 addrser.sin_family = AF_INET; //服务器端所用的协议家族 addrser.sin_port = htons(SERVER_PORT); //设置服务器的端口号 addrser.sin_addr.s_addr = inet_addr(SERVER_IP); //设置服务器端的IP地址 socklen_t addrlen = sizeof(struct sockaddr); //得到服务器的地址结构的大小 int res = bind(sockser, (struct sockaddr*)&addrser, addrlen); //绑定服务器的套接字和服务器的地址结构 if(res == -1){ perror("bind"); } listen(sockser, QUEUE_SIZE); //监听 int sockconn; while(1){ sockconn = accept(sockser, (struct sockaddr*)&addrcli, &addrlen); //服务器接受客户端的连接 if(sockconn == -1){ perror("accept"); } printf("client[%d] connect server ok.\n", addrcli.sin_port); pid_t pid = fork(); //创建进程用于服务 if(pid == 0){ handler(sockconn); //子进程处理客户端的请求函数 exit(0); }else if(pid > 0){ close(sockconn); //父进程关闭已连接套接字 continue; }else{ printf("fork error.\n"); } } close(sockser); //关闭服务器端的套接字 return 0;}
客户端的代码如下:
#include "unp.h"void Input(Oper *op);void help();int main(int ac, char *av[]){ int sockcli = socket(AF_INET, SOCK_STREAM, 0); //得到客户端的套接字 if(sockcli == -1){ perror("socket"); } struct sockaddr_in addrser; //服务器的地址结构 addrser.sin_family = AF_INET; //设置服务器的协议家族 addrser.sin_port = htons(SERVER_PORT); //设置服务器的端口号 addrser.sin_addr.s_addr = inet_addr(SERVER_IP); //设置服务器的IP地址 socklen_t addrlen = sizeof(struct sockaddr); //得到服务器的地址结构大小 int res = connect(sockcli, (struct sockaddr*)&addrser, addrlen); //连接服务器 if(res == -1){ perror("connect"); }else{ printf("client connect server ok.\n"); } char cmd[20]; //用于存储客户所请求的服务名称 Oper op; //客户的请求的结构体(包括客户请求的服务类型,输入的数据) int result; //由服务器发回的请求的服务结果 //客户发送请求并接收请求结果 while(1){ printf("please input cmd:>"); scanf("%s", cmd); if(strcmp(cmd, "add") == 0){ op.oper = ADD; Input(&op); }else if(strcmp(cmd, "sub") == 0){ op.oper = SUB; Input(&op); }else if(strcmp(cmd, "mul") == 0){ op.oper = MUL; Input(&op); }else if(strcmp(cmd, "div") == 0){ op.oper = DIV; while(1){ Input(&op); if(op.op2 == 0){ //除数为0时重新输入 perror("op2 == 0 error"); printf("please input again.\n"); continue; } break; } }else if(strcmp(cmd, "help") == 0){ help(); continue; }else if(strcmp(cmd, "quit") == 0){ op.oper = QUIT; }else{ printf("your input is invalid.\n"); } int res = send(sockcli, (char *)&op, sizeof(op), 0); //发送客户的请求给服务器 if(res == -1){ perror("send"); } if(op.oper == QUIT){ break; } recv(sockcli, &result, sizeof(int), 0); //接收服务器发送回来的结果 printf("result = %d\n", result); } close(sockcli); //关闭客户端的套接字 return 0;}void Input(Oper *op) //得到进行操作的两个数{ printf("please input op1 add op2.\n"); scanf("%d, %d", &op->op1, &op->op2);}void help() //提示信息{ printf("#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*\n"); printf("^^^^^^^^^version^^^^^^^^^ : ^^^^^v1.0^^^^^^^^^^\n"); printf("^^^^^^^^^author^^^^^^^^^^ : ^^^^^haha^^^^^^^^^^\n"); printf("~*~*~*~*~cmd~*~*~*~*~*~*~ ~*~*~describe~*~*~\n"); printf("~*~*~*~*~add~*~*~*~*~*~*~ ~*~*~op1 + op2~*~*\n"); printf("~*~*~*~*~sub~*~*~*~*~*~*~ ~*~*~op1 - op2~*~*\n"); printf("~*~*~*~*~mul~*~*~*~*~*~*~ ~*~*~op1 * op2~*~*\n"); printf("~*~*~*~*~div~*~*~*~*~*~*~ ~*~*~op1 / op2~*~*\n"); printf("#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*\n");}
头文件
#include <iostream>#include <unistd.h>#include <signal.h>#include <stdio.h>#include <arpa/inet.h>#include <netinet/in.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#define SERVER_IP "127.0.0.1"#define SERVER_PORT 7070#define QUEUE_SIZE 5typedef enum{ADD, SUB, MUL, DIV, QUIT}OPER_STATE;typedef struct Oper{ OPER_STATE oper; int op1; int op2;}Oper;
1 0
- 多进程的网络服务的一般模型
- 多线程网络服务的一般模型
- python中多进程的一般建议
- 从零实现一个最精简的select网络服务模型
- nginx的多进程模型
- AIX网络服务的启动
- Amazon的网络服务aws
- 虚函数的一般实现模型
- 时间序列模型分析的一般步骤
- nginx的进程模型
- nginx的进程模型
- Nginx的进程模型
- nginx的进程模型
- IE的进程模型
- 进程的三态模型
- Swoole的进程模型
- nginx的进程模型
- 进程的三态模型
- vi编辑器
- Oracle 11G 维护配置命令
- Caffe Ubuntu 下的调试
- count(*),count(1)和count(主键)的区别
- pixhawk(ArduCopter V3.3)源码分析—导航制导部分
- 多进程的网络服务的一般模型
- 【编程学习】算法之排序小结
- Install and test nginx on Ubuntu 14.04
- 项目:TEDxDUT 演讲报名网站
- JavaScript DOM对象,控制html元素
- Exception和继承自Exception的RuntimeException区别
- 指向学生类的指针
- 【java集合一】根接口Collection、Map
- Android__数据存储