当前位置: 首页 > news >正文

我想做个网站做导航网站电脑设备

我想做个网站,做导航网站电脑设备,wordpress 去除右边,做电影网站需要注意事项0302 多进程网络服务器架构 ​专栏内容#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页#xff1a;我的主页 管理社区#xff1a;开源数据库 座右铭#xff1a;天行健#xff0c;君子以自强不息#xff1b;地势坤#xff0c;君子以厚德载物. 一、概…0302 多进程网络服务器架构 ​专栏内容 postgresql使用入门基础手写数据库toadb并发编程 个人主页我的主页 管理社区开源数据库 座右铭天行健君子以自强不息地势坤君子以厚德载物. 一、概述 在大规模数据处理中会有大量的客户端接入同一台服务器每个客户端都需要长时间提供服务。 服务器采用中心化的部署而客户端往往分散在不同机器上服务器与客户端之间跨网络通信一般采用C/S架构。 而服务端的架构需要能应对大量并发客户端同时可以给每个客户端独占的服务这就用到了多任务的网络模型架构下面我们来看看用多进程如何实现。 二、多路复用的网络模型 C/S架构中处理大量的网络请求需要一套基于多路复用的网络处理模型。 可以同时处理网络连接请求和网络数据传递;减少程序的阻塞时间避免无效的CPU消耗适应不同的并发规模 以此为目标实现如下网络模型。 2.1 服务端网络监听 多路复用模型这里采用了epoll方式如果自己的平台不支持可以换为select或者poll的方式。 代码如下 #include stdio.h #include stdlib.h #include string.h #include unistd.h #include arpa/inet.h #include sys/epoll.h #include fcntl.h #include errno.h #define MAX_EVENTS 10 #define BUFFER_SIZE 1024 #define PORT 8080 // 设置文件描述符为非阻塞模式 int set_nonblocking(int fd) { int flags, s; flags fcntl(fd, F_GETFL, 0); if (flags -1) { perror(fcntl F_GETFL); return -1; } flags | O_NONBLOCK; s fcntl(fd, F_SETFL, flags); if (s -1) { perror(fcntl F_SETFL); return -1; } return 0; } int main() { int listen_fd, conn_fd, nfds, epoll_fd; struct sockaddr_in server_addr; struct epoll_event ev, events[MAX_EVENTS]; char buffer[BUFFER_SIZE]; ssize_t count; // 创建监听socket listen_fd socket(AF_INET, SOCK_STREAM, 0); if (listen_fd -1) { perror(socket); exit(EXIT_FAILURE); } // 设置非阻塞模式 if (set_nonblocking(listen_fd) -1) { close(listen_fd); exit(EXIT_FAILURE); } // 绑定地址和端口 server_addr.sin_family AF_INET; server_addr.sin_addr.s_addr INADDR_ANY; server_addr.sin_port htons(PORT); if (bind(listen_fd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { perror(bind); close(listen_fd); exit(EXIT_FAILURE); } // 开始监听 if (listen(listen_fd, SOMAXCONN) -1) { perror(listen); close(listen_fd); exit(EXIT_FAILURE); } // 创建epoll实例 epoll_fd epoll_create1(0); if (epoll_fd -1) { perror(epoll_create1); close(listen_fd); exit(EXIT_FAILURE); } // 添加监听socket到epoll实例 ev.events EPOLLIN; ev.data.fd listen_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, ev) -1) { perror(epoll_ctl: listen_fd); close(listen_fd); close(epoll_fd); exit(EXIT_FAILURE); } // 主循环 while (1) { nfds epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (nfds -1) { perror(epoll_wait); exit(EXIT_FAILURE); } for (int n 0; n nfds; n) { if (events[n].data.fd listen_fd) { // 新的连接 conn_fd accept(listen_fd, NULL, NULL); if (conn_fd -1) { perror(accept); continue; } // 设置非阻塞模式 if (set_nonblocking(conn_fd) -1) { close(conn_fd); continue; } // 添加新的连接socket到epoll实例 ev.events EPOLLIN | EPOLLET; ev.data.fd conn_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, ev) -1) { perror(epoll_ctl: conn_fd); close(conn_fd); } } else { // 处理读事件 conn_fd events[n].data.fd; while ((count read(conn_fd, buffer, BUFFER_SIZE)) 0) { // 处理接收到的数据这里简单回显 write(conn_fd, buffer, count); } if (count -1 errno ! EAGAIN) { // 出现错误或连接关闭 close(conn_fd); } else if (count 0) { // 连接关闭 close(conn_fd); } // 从epoll实例中移除已关闭的socket if (count 0 errno ! EAGAIN) { ev.events 0; epoll_ctl(epoll_fd, EPOLL_CTL_DEL, conn_fd, ev); }} } } close(listen_fd); close(epoll_fd); return 0; }说明 TCP服务端的基本步骤创建socket设置为非阻塞模式绑定IP与端口开启监听这里服务端的socket需要设置为非阻塞模式因为我们是在单进程中处理多个连接每个连接不能阻塞等待然后加入到epoll监听池中开始epoll事件的等待这里只处理接收事件如果有服务端socket的接收事件那么说明有客户端连接消息进行accep创建客户端连接的socket同样将客户端连接的socket设置为非阻塞理由同上加入epoll临听池中同样也只处理接收事件如果有客户端连接的socket上的接收事件那么说明客户端正在给服务端发消息收到客户端消息后这里只是简单处理原样再发给客户端如果客户端关闭或出错将客户端连接关闭并从epoll临听池中移除 2.2 客户端测试 现在我们来编写一个简单的客户端模拟程序测试一下多路复用的网络框架。 /** ex020302_client.c*/#include stdio.h #include stdlib.h #include string.h #include unistd.h #include arpa/inet.h #define SERVER_IP 127.0.0.1 #define SERVER_PORT 4808 #define BUFFER_SIZE 1024 #define CLIENT_SEND_CNT 20int main() { int sockfd; struct sockaddr_in server_addr; char buffer[BUFFER_SIZE] {0}; const char *message Hello, Server!; // 创建套接字 if ((sockfd socket(AF_INET, SOCK_STREAM, 0)) 0) { perror(socket creation failed); exit(EXIT_FAILURE); } // 配置服务器地址信息 server_addr.sin_family AF_INET; server_addr.sin_port htons(SERVER_PORT); // 将IP地址从字符串转换为二进制形式 if (inet_pton(AF_INET, SERVER_IP, server_addr.sin_addr) 0) { perror(Invalid address/ Address not supported); close(sockfd); exit(EXIT_FAILURE); } // 连接到服务器 if (connect(sockfd, (struct sockaddr *)server_addr, sizeof(server_addr)) 0) { perror(Connection Failed); close(sockfd); exit(EXIT_FAILURE); } for(int i 0; i CLIENT_SEND_CNT; i){// 发送消息到服务器 send(sockfd, message, strlen(message), 0); printf(Message sent: %s\n, message); // 接收服务器的响应 int bytes_received recv(sockfd, buffer, BUFFER_SIZE - 1, 0); if (bytes_received 0) { perror(Error in receiving); } else if (bytes_received 0) { printf(Server closed the connection\n); } else { buffer[bytes_received] \0; // 确保字符串以空字符结尾 printf(Message received from server: %s\n, buffer); } sleep(1);}// 关闭套接字 close(sockfd); return 0; }说明 TCP客户端建立的基本步骤创建socket初始化服务端地址连接服务器;然后向服务端发送相同的消息每次发送完成后等待接收消息 2.3 客户端测试 可以看到服务端处理客户端的请求时都是按照接收到的顺序进行串行处理 当客户端的数量达到成百上千时对客户端的响应时间就会出现非常明显的延迟 这种延迟会随着业务的复杂度而放大。 这时就需要充分利用多核CPU硬件资源来进行并发任务的处理。 三、多进程服务处理 上面是在单个任务进程中处理了监听和大量任务连接的网络处理各客户端连接的服务会相互影响实际是串行化处理的。 要让大量的客户端能同时被响应需要采用多任务的方式那么在上面的网络模型基础上加入多进程服务端为每个客户端连接准备一个独立的进程这样就可以及时响应。 3.1 多进程架构 首先我们利用前面几个章节的介绍来搭建一个多进程的代码架构由主进程根据需要进行创建子进程并且由主进程进行全局的控制。 /** ex020302_netprocess.c*/ #include stdio.h #include stdlib.h #include string.h #include unistd.h #include arpa/inet.h #include sys/epoll.h #include fcntl.h #include errno.h #define MAX_EVENTS 10 #define BUFFER_SIZE 1024 #define PORT 4808 void daemon_fork() {int pid -1;pid fork();if(pid 0){printf(fork error[%s]\n,strerror(errno));exit(-1);}else if(pid 0){// parent exit.exit(0);}else {// child daemonreturn;} }void subprocess(int sock) {int pid -1;pid fork();if(pid 0){printf(fork error[%s]\n,strerror(errno));exit(-1);}else if(pid 0){// parent.close(sock);return;}else {// child close(listen_fd);processMsg(sock);exit(0);} } 说明 daemon服务程序函数这个前一章节已经介绍过了服务端以后台进程的方式运行子进程任务处理函数这里创建的是任务子进程并在子进程中调用消息处理函数这里需要注意的是在子进程中要关闭服务端的socket同时在父进程中要关闭客户端连接的socket; 因为父子进程会复制内存空间但是在各自的进程中已经不再需要 3.2 并发网络处理模型 现在就可以将上面的多路复用网络处理放入多进程架构中处理逻辑进行如下切分 服务端监听socket初始化多路复用器的初始化等都放在主进程中作为服务端网络初始化的一部分每个客户端连接的socket以及它的读写消息处理逻辑放在子进程中这样每个客户端连接对应一个后台服务子进程创建子进程的时机也就是在主进程中接收到新连接时创建新连接成功后就可以新建子进程进行处理而子进程的退出时间就是客户端断开连接或者处理出错时 void initializeServerNet() {struct sockaddr_in server_addr; // 创建监听socket listen_fd socket(AF_INET, SOCK_STREAM, 0); if (listen_fd -1) { perror(socket); exit(EXIT_FAILURE); } // 绑定地址和端口 server_addr.sin_family AF_INET; server_addr.sin_addr.s_addr INADDR_ANY; server_addr.sin_port htons(PORT); if (bind(listen_fd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { perror(bind); close(listen_fd); exit(EXIT_FAILURE); }// 开始监听if (listen(listen_fd, SOMAXCONN) -1){perror(listen);close(listen_fd);exit(EXIT_FAILURE);} }void closeServerFd() {close(listen_fd); }void dispatchLoop() {int conn_fd; // 主循环 while (1) { // 新的连接 conn_fd accept(listen_fd, NULL, NULL); if (conn_fd -1) { perror(accept); sleep(1);continue; }subprocess(conn_fd);} }void processMsg(int sock) {char buffer[BUFFER_SIZE]; ssize_t count; printf(serv-process:%d start.\n);while ((count read(sock, buffer, BUFFER_SIZE)) 0){// 处理接收到的数据这里简单回显write(sock, buffer, count);}if (count -1 errno ! EAGAIN){// 出现错误或连接关闭close(sock);}else if (count 0){// 连接关闭close(sock);}printf(serv-process:%d exit.\n); }那么主程序实现如下 void daemon_fork(); void subprocess(int sock); void processMsg(int sock);void initializeServerNet(); void closeServerFd(); void dispatchLoop();int listen_fd;int main(int argc ,char *argv[]) {daemon_fork();initializeServerNet();dispatchLoop();closeServerFd();return 0; }在主进程中先进程服务端初始化然后就可以开始监听并接收客户端的连接当有客户端连接时就创建客户端连接并启动子进程与该客户端进行网络通信子进程在客户端断开连接或出错时就会退出 2.3 客户端测试 可以看到将客户端发送次数调大后开启的客户端越多服务端启动的子进程也就会越多 此时可以看到服务端每个进程的CPU使用率并不是很高 但是随着客户端数量越来越多服务端进程数量超过CPU核数时就会增加系统的负担 四、总结 本文主要介绍了基于多进程架构的网络服务器的设计与实现在多进程架构中每个客户端会有一个服务端的进程专门处理通信增加了对客户端消息的响应效率提升了并发处理能力。 结尾 非常感谢大家的支持在浏览的同时别忘了留下您宝贵的评论如果觉得值得鼓励请点赞收藏我会更加努力 作者邮箱studysenllang.onaliyun.com 如有错误或者疏漏欢迎指出互相学习。 注未经同意不得转载
http://www.hkea.cn/news/14414249/

相关文章:

  • 南昌企业建设网站开发wordpress 动作hook
  • 网站建设 发短信文案网络推销平台有哪些
  • 网站制作费用属于广告费吗广州公认的第一富人区
  • 网站做ddns解析网站编程技术
  • 成都哪家做网站比较好做电影网站用什么软件叫什么名字
  • 宁波城乡住房建设局网站网络购物消费者行为论文
  • 找网站做网站做网站网站的备用金怎么做凭证
  • 注册网站不需要手机验证的装修网平台
  • 模板网站seo网站建设需求文案
  • 网站开发学什么六安马启兵
  • 微网站开发平台 开源优化网络工程师
  • 如何采集网站内容图片在线生成网址
  • 免费的企业网站建设流程wordpress数据库移动
  • 定制网站开发平台网站和软件是怎么做的
  • 爱站seowordpress单页导航
  • 打电话说帮忙做网站wordpress官方插件
  • 企业网站制作建设的框架有哪几种佛山搜索seo优化排名
  • 英文网站支付怎么做超变攻速传奇一秒20刀
  • 一站式发稿平台国内知名软件开发公司
  • 上海黄浦区网站建设汕头市城乡与住房建设局
  • 网站开发公司 商业计划书搭建网站是什么工作
  • 建设企业网站怎么样全国学校信息查询官网
  • 长沙网站制作工作室知名公司成都自然排名优化
  • 项目外包网站网站视频怎么做的好
  • 在阿里巴巴做网站多少钱2019长春做网站seo的
  • 东莞纸箱厂东莞网站建设网站建设在线
  • 苏州网络科技公司建网站凡科快图官方下载
  • 柳市网站建设哪家好网站设计与开发期末考试题
  • 市桥网站建设培训学校wordpress壁纸小程序
  • 岳阳企业网站定制开发做网站用eclipse吗