Linux高并发服务器案例演示

在网络通信中,我们常常的服务器经常会受到成千上万的请求提示,而电脑会根据请求建立相对应的socket链接,但是接触过Linux网络编程的人都知道,Linux链接和客户端建立连接,会经过四步(这里以TCP说明)

第一步,创建socket对应的描述符,这里设置好socket的协议类型以及通信类型(TCP/UDP)

#include <sys/types.h>/* See NOTES */

#include<sys/socket.h>

int socket(int domain, int type, int protocol);

具体的使用方法可以使用man手册查看socket函数

第二步,绑定端口,以及相应的ip地址(服务器不用设置)

#include <sys/types.h> /* See NOTES */

#include <sys/socket.h>

intbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

具体的使用方法可以使用man手册查看bind函数

第三步,监听socket,并且设置最大监听数

#include <sys/types.h> /* SeeNOTES */

#include<sys/socket.h>

int listen(int sockfd, int backlog);

具体的使用方法可以使用man手册查看listen函数

第四步,接受客户端的连接

#include <sys/types.h>      /* See NOTES */

#include<sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t*addrlen);

具体的使用方法可以使用man手册查看accept函数

注意:

由于上述四步socket建立链接中,accept是阻塞的,意味着如果有很多人同时发出socket请求的时候,服务器只会接收到一少部分的连接,其他都在阻塞队列排队,甚至丢失!甚至建立链接后一旦涉及服务器读写操作时候,涉及到读写,也是会遇到阻塞的!(假设每个用户连接服务器需要0.1秒,那么10000人连接的话则需要1000秒)这样会让服务器浪费大量时间在阻塞过程,所以我们要做的,就是尽可能的让系统发挥出他的性能,让更多的人能够连接系统,却不用花那么长时间。

具体实现方法:

使用epoll分路技术,让accept不陷入阻塞,当那个客户端发出请求,则处理发出请求的客户端信息,这时候因为客户端发出请求,则必定有读写操作,所以读写操作不用去掉阻塞。

服务器代码:

//模拟接收每个客户端发来的请求后并往dbg.txt文件写入一个字节
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
void sig_handle(int sig)
{printf("recv signal :%d\n",sig);
}
int main(int argc, char * argv[])
{signal(SIGPIPE,sig_handle);if (argc<2){printf("usage:%s + [count]\n",argv[0]);return 0;}unlink("dbg.txt");int dbg = open("dbg.txt",O_CREAT|O_APPEND|O_RDWR,0666);int count = atoi(argv[1]);int fd = socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in addr;memset(&addr,0,sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(9988);int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));if (ret ==-1){perror("bind");return 0;}listen(fd,250);int is_child_process = 0;//判断在哪个进程中,父进程0,子进程1for (int i = 0 ; i < count ; i++){pid_t pid = fork();if (pid==0){is_child_process = 1;break;}}struct epoll_event ev;ev.events = EPOLLIN|EPOLLET;ev.data.fd = fd;int epfd = epoll_create(1024);//建立epfd的描述符int flags = fcntl(fd,F_GETFL);flags |= O_NONBLOCK;fcntl(fd,F_SETFL,flags);epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);while (1){struct epoll_event evs[10];int process_count = epoll_wait(epfd,evs,10,5000);if (process_count == 0) continue;//如果监听的进程都没有事件产生,则再次进入循环,继续监听for (int i = 0 ; i < process_count ;i++){if (evs[i].data.fd == fd){//当进程中的socket描述符是server的socket本身时候,则accept否则就直接操作int ret = accept(evs[i].data.fd,NULL,NULL);if (ret == -1){printf("errno:%s",strerror(errno));//其他错误,直接exitbreak;}ev.data.fd = ret;epoll_ctl(epfd,EPOLL_CTL_ADD,ret,&ev);}else{//read or writechar buf[1024];int ret = read(evs[i].data.fd,buf,sizeof(buf));if (ret == -1){perror("read");if (errno == EINTR)break;exit(0);}else if (ret == 0){//normal exitclose(evs[i].data.fd);break;}//printf("recv data %s from pid:%d\n",buf,getpid());write(dbg,"1",1);}}}if (!is_child_process){for (int i = 0 ; i < count; i ++){wait(NULL);//等待所有的子进程退出为止}}return 0;
}

测试客户端向服务器发请求代码:

//模拟有20000个客户端同时向服务器发请求
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <string.h>
#define PROCESS_COUNT 20000
void func(int argc,char * argv[])
{int fd =socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(9988);addr.sin_addr.s_addr =inet_addr("127.0.0.1");connect(fd,(structsockaddr*)&addr,sizeof(addr));if (argc==2)write(fd,argv[1],strlen(argv[1]));elsewrite(fd,"1",1);char buf[1024];//recv(fd,buf,sizeof(buf),0);
}int main(int argc,char *argv[])
{for (int i = 0 ; i <PROCESS_COUNT; i++){pid_t pid = fork();if (pid == 0){func(argc,argv);return 0;}}for (int i = 0 ; i <PROCESS_COUNT; i++){wait(NULL);}return 0;
}

结果分析:不同的电脑测试结果略有不同,我的客户端定义有20000个同时向服务器发请求,结果处理的请求大概有15500左右,不同的电脑最高并发数略有不同。成功的解决了多用户同时向一个服务器发请求的问题

Linux高并发服务器解决方案相关推荐

  1. Linux 高并发服务器开发

    该文章是通过观看牛客网的视频整理所得,以及在实践过程中遇到的问题及解决方案的整理总结. Linux 高并发服务器开发 linux 系统编程 linux 环境的搭建 环境搭建需要的软件 虚拟机中安装 u ...

  2. Linux高并发服务器开发---笔记2(多进程)

    0630 第4章 项目制作与技能提升 4.0 视频课链接 4.1 项目介绍与环境搭建 4.2 Linux系统编程1.4.3 Linux系统编程2 4.4 多进程 1-9 10.进程间通信☆☆☆ 进程间 ...

  3. Linux高并发服务器开发---笔记1(环境搭建、系统编程、多进程)

    0613 第4章 项目制作与技能提升 4.0 视频课链接 4.1 项目介绍与环境搭建 4.1.1 项目介绍 4.1.2 开发环境搭建 ①安装Linux系统.XSHELL.XFTP.Visual Stu ...

  4. Linux 高并发服务器实战 - 2 Linux多进程开发

    Linux 高并发服务器实战 - 2 Linux多进程开发 进程概述 概念1: 概念2: 微观而言,单CPU任意时刻只能运行一个程序 并发:两个队列交替使用一台咖啡机 并行:两个队列同时使用两台咖啡机 ...

  5. Linux高并发服务器开发---笔记4(网络编程)

    0705 第4章 项目制作与技能提升 4.0 视频课链接 4.1 项目介绍与环境搭建 4.2 Linux系统编程1.4.3 Linux系统编程2 4.4 多进程 1-9 10.进程间通信☆☆☆ 4.5 ...

  6. [Linux 高并发服务器]网络基础

    [Linux 高并发服务器]网络基础 文章概述 该博客为牛客网C++项目课:Linux高并发服务器 个人笔记 作者信息 NEFU 2020级 zsl ID:fishingrod/鱼竿钓鱼干 Email ...

  7. [Linux 高并发服务器]GDB调试

    [Linux 高并发服务器]GDB调试 [Linux 高并发服务器]GDB调试 [Linux 高并发服务器]GDB调试 GDB是什么 预先准备 基本命令 例子 进入和退出gdb 获取帮助 查看文件代码 ...

  8. Linux 高并发服务器实战 - 1 Linux系统编程入门

    Linux 高并发服务器实战-1Linux系统编程入门 在本机和服务器端设置公共密钥(配置免密登录) 在本机cmd里输入 ssh-keygen -t rsa,生成本机的公密钥 在服务器端里也配置 ss ...

  9. Linux高并发服务器开发—项目实战

    1.阻塞/非阻塞.同步/异步(网络IO) 典型的一次IO的两个阶段是什么?数据就绪 和 数据读写 数据就绪:根据系统IO操作的就绪状态 阻塞--非阻塞 数据读写:根据应用程序和内核的交互方式 同步-- ...

最新文章

  1. Python 自动化-pywinauto库定位树结构控件里的树节点实例演示
  2. 嵌入式码农的10年Bug调试经验,值得一看
  3. 伯努利数(详解 + 例题 :P3711 仓鼠的数学题)
  4. jQuery学习总结06-插件开发
  5. Socket编程实践(9) --套接字IO超时设置方法
  6. TypeScript学习(二):任意类型及推论
  7. TensorFlow 学习(十五)—— tensorflow.python.platform
  8. 使用samba完成Linux服务器与Windows之间的映射
  9. android wps mac 下载地址,wps for mac下载
  10. ansible 远程启动程序ansible结束后程序也被关闭
  11. 让PS可以保存为ICO格式
  12. 树莓派使用排线摄像头和远程视频监控
  13. 空格键 还是 Tab键?
  14. matlab 色温图,一张图看懂“色温”的通用范围标准!摄影白平衡其实就这么简单...
  15. JAVA封神榜之九尾妖狐,盘点《封神演义》中的7位散修大妖,孔宣排第三,九尾妖狐排第六...
  16. 怎么制作珠宝首饰类标签
  17. 最新2018手机号码正则表达式
  18. 华为快应用-修改IDE的主题颜色
  19. 5G PC来了!联想携YOGA 5G笔记本亮相ChinaJoy
  20. PHP开发的简洁的导航网站源码多种主题风格切换

热门文章

  1. 【市场营销学三】企业战略与营销管理
  2. linux efi shell,EFI Shell 命令说明
  3. 在SQL SERVER中查找用分隔符分隔的数据
  4. mongodb——查询文档内部属性以及数组
  5. 华为P6刷机包 移动版 基于EmotionUI B508适配 MIUI V5 4.9.22发布 更新优化
  6. 服务器上的文件如何查看,如何查询服务器上的文件来源
  7. eMMC5.1入门教程【1】eMMC简介与协议概览
  8. java实现world文档转pdf
  9. 量子三体问题: Landau Fall
  10. 量子计算:第四次工业革命的引擎