今天写程序用到epoll的模型,翻出原先的代码跑了一下,看到原来define的最大的处理用户上限,感觉有些不妥,所以决定测试一下我的ubuntu 16.04,1G内存的单机上究竟可以建立多少个连接。虽然网上有很多这方面的案例,但是我还是决定自己测试一下,印象深刻,对问题场景有更深的印象。
如果文中有错误或者不全面的地方,希望大家指正。
纠正博客中的错误:我的客户端和服务器在单机上进行,所以其实端口是被客户端消耗掉的,所以我本文中说的端口限制只能限制开放的客户端的上限,实际并不能限制服务器处理的连接数的上限,理论上一台服务器处理的连接数在内存足够多的情况下是可以处理无数连接的(2^48理论数量)。
这篇文章中我没有理解的概念是listen的soccketfd和accept返回的socketfd的不同,listen的socket创建的socketfd绑定的端口,这个socketfd是告诉TCP/IP协议栈这个socketfd指向绑定的ip+port,以后有发往这个ip+port的数据包都是发给这个socket,accept返回的connfd是用来标识一个连接五元组的,所以,tcp服务器能处理的连接数实际是由五元组来确定的,更准确的说是由客户端的ip+port来决定连接数的,对于ipv4地址232,port是216,所以理论的连接数最多是2^48。但实际情况中这个和设备的内存,一条tcp连接占用的内存有关,所以,要切记,65535并不是单机服务器处理的连接数上限。65535硬要说是上限,那就是单机开放不同客户端的连接数。实际这也是不确切的,单机情况下,可以通过设置虚拟ip来突破单机65535这个上限。后续我会把我单机测试的服务器最大连接数的测试实例、如何修改内核参数来增大这个连接数的方法发出来。
我测试代码是自己写的,也很简单,就是客户端程序不停的请求连接(这里都是短链接,长连接和需要数据交互的连接请求情况可能和本文的情况不同,长连接就不会有大量的time_wait情况产生),服务器接收了客户端的请求建立连接,这种情况下,客户端不停的创建socket描述符,起初我的系统设置的上限是1024(ulimit -n查看)。
上代码:
server:
#include /* basic system data types */
#include /* basic socket definitions */
#include /* sockaddr_in{} and other Internet defns */
#include /* inet(3) functions */
#include /* epoll function */
#include /* nonblocking */
#include /*setrlimit */
#include
#include
#include
#include
#define MAXEPOLLSIZE 65535
#define MAXLINE 10
int setnonblocking(int sockfd)
{
if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
return -1;
}
return 0;
}
static int iCount = 0;
static