Linux(服务器编程):百万并发服务器系统参数调优( 五 )
#define MAX_EPOLL_EVENTS (1024 * 512)
文章插图
- 上面所有的内容修改完成之后 , 进入下面的第2次测试
- 左侧运行服务端程序reactor(111.229.177.161:8888) , 右侧运行两个客户端程序mul_port_client_epoll去连接服务器
- 效果如下:
- 左侧服务端持续接收客户端的连接
- 右侧两个客户端向服务端发起连接 , 其中一个客户端只连接了两万多个就报错退出了 , 另一个客户端只连接了一万多个就报错退出了
- 左侧服务端没有报错 , 只是没有客户端再连接进来了
文章插图
文章插图
原因分析
- 此处要介绍“五元组”的概念了 , 这个概念在下面的几次测试中都要用到
- 一个套接字fd就对应一个“五元组” , 一个五元组包含下面几项内容:
- 1.源IP地址
- 2.目的IP地址
- 3.源端口
- 4.目的端口
- 5.协议类型(TCP、UDP等)
文章插图
- 因此 , 我们上面的两个客户端加起来最多只能创建四万个套接字就报错的原因是:
- 源IP地址、目的IP地址、协议类型(TCP)这三者都保持不变、目的端口只有一个也保持不变 , 唯一可以变化的就是源端口(也就是客户端的端口)
- 我们知道 , 一个系统的端口最多只能有65535个 , 其中有一些已经被其他服务使用了 , 因此客户端可以使用的端口大概只有四五万个 , 所以客户端也就只能创建四五万个套接字 , 所以上面我们两个客户端总共加起来只创建了四五万个套接字就不能再继续创建套接字了
- 概括来说 , 你能有多少种“五元组”类型 , 那么你就能建立多少个套接字连接
文章插图
解决方案
- 通过上面的分析我们知道 , 主要的限制原因就在端口的限制上 , 因此下面我们让服务端程序监听在多个端口上 , 这样一来可以使用的“五元组”组合就可以更多 , 那么我们可以创建的套接字fd也就更多
文章插图
- 第一步:
- 修改服务端程序reactor.c , 使其监听在5个端口上 , 也就是启动了5个Tcp Server(随意多少个 , 只要端口多了 , 就能承载更多的客户端 , 此处我们就只设置为5个)
- 代码变化不多 , 只是新增了一个LISTEN_PORT_COUNT宏 , 然后修改了main()函数使其监听在5个端口上 , 其余代码全部不变
- 修改完成之后重新编译
// reactor.c其余代码不变, 只需要修改下面的内容即可#include #include #include #include #include #include #include #include #include #include#define BUFFER_LENGTH4096#define MAX_EPOLL_EVENTS 1024#define SERVER_PORT8888 // 新增一个宏, 表示监听的端口数量#define LISTEN_PORT_COUNT5 typedef int NCALLBACK(int ,int, void*); struct ntyevent { int fd;int events;void *arg;int (*callback)(int fd, int events, void *arg); int status;char buffer[BUFFER_LENGTH]; int length; long last_active;}; struct ntyreactor { int epfd;struct ntyevent *events;}; int recv_cb(int fd, int events, void *arg);int send_cb(int fd, int events, void *arg);int nty_event_set(struct ntyevent *ev, int fd, NCALLBACK callback, void *arg) { ev->fd = fd; ev->callback = callback; ev->events = 0; ev->arg = arg; ev->last_active = time(NULL);return 0;} int nty_event_add(int epfd, int events, struct ntyevent *ev) {struct epoll_event ep_ev = {0, {0}}; ep_ev.data.ptr = ev; ep_ev.events = ev->events = events;int op; if (ev->status == 1) {op = EPOLL_CTL_MOD; } else {op = EPOLL_CTL_ADD;ev->status = 1; }if (epoll_ctl(epfd, op, ev->fd,return -1; }return 0;} int nty_event_del(int epfd, struct ntyevent *ev) {struct epoll_event ep_ev = {0, {0}}; if (ev->status != 1) { return -1; }ep_ev.data.ptr = ev; ev->status = 0; epoll_ctl(epfd, EPOLL_CTL_DEL, ev->fd,return 0;} int recv_cb(int fd, int events, void *arg) { struct ntyreactor *reactor = (struct ntyreactor*)arg; struct ntyevent *ev = reactor->events + fd;int len = recv(fd, ev->buffer, BUFFER_LENGTH, 0); nty_event_del(reactor->epfd, ev);if (len > 0) {ev->length = len;ev->buffer[len] = '\0';printf("C[%d]:%s\n", fd, ev->buffer);nty_event_set(ev, fd, send_cb, reactor);nty_event_add(reactor->epfd, EPOLLOUT, ev);} else if (len == 0) {close(ev->fd); printf("[fd=%d] pos[%ld], closed\n", fd, ev-reactor->events);} else { //if(errno == EAGAIN || errno == EWOULDBLOCK) // continue; return 0;close(ev->fd); printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));}return len;} int send_cb(int fd, int events, void *arg) {struct ntyreactor *reactor = (struct ntyreactor*)arg; struct ntyevent *ev = reactor->events + fd;int len = send(fd, ev->buffer, ev->length, 0); if (len > 0) { printf("send[fd=%d], [%d]%s\n", fd, len, ev->buffer);nty_event_del(reactor->epfd, ev);nty_event_set(ev, fd, recv_cb, reactor);nty_event_add(reactor->epfd, EPOLLIN, ev);} else {close(ev->fd);nty_event_del(reactor->epfd, ev); printf("send[fd=%d] error %s\n", fd, strerror(errno)); }return len;} int accept_cb(int fd, int events, void *arg) { struct ntyreactor *reactor = (struct ntyreactor*)arg; if (reactor == NULL) return -1; struct sockaddr_in client_addr; socklen_t len = sizeof(client_addr); int clientfd; if ((clientfd = accept(fd, (struct sockaddr*) return -1; }int i = 0; do { for (i = 0;i
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Git服务器配置错误导致日产汽车源码在网上泄露
- 机器人|万州区举办“中国梦科技梦”机器人编程大赛
- Linux Kernel 5.10.5发布:禁用FBCON加速滚动特性
- Linux 5.11开始围绕PCI Express 6.0进行早期准备
- Fedora正在寻求协助 希望加快Linux 5.10 LTS内核测试进度
- Linux Mint 20.1 Ulyssa稳定版已确定延期至2021年初发布
- 英特尔Xe GPU在Linux 5.11上的性能表现不错
- MIPS架构厂商日渐式微 Linux报告其漏洞遭遇困难
- 手把手配置HLS流媒体服务器
- 2020年科技十大“翻车”现场:谷歌服务器真的有点累了……