python - 为什么我可以在 Python 中打开超过 1024 个套接字?
问题描述
我发现我可以在 Python 中打开近 8156 个套接字连接,但我调用
resource.getrlimit(resource.RLIMIT_NOFILE) => (1024, 1048576)
这是否意味着文件描述符限制为 1024?如果不是,为什么这个数字是 8000+,而不是接近 1048576?
但是在相同的资源条件下,我只能在 C++ 中几乎打开 1024 个套接字连接
我的操作系统是 ubuntu,Python 版本是 3.6.8
ulimit -n is 1024
ulimit -Hn is 1048576
刚才我再测试一下如果我在C++代码中将RLIMIT_NOFILE软限制设置为和硬限制一样,socket连接数可以增加到8000+,和Python一样,但是不能再增长了,那么有什么关系呢?
代码在这里,C++ 服务器和 Python 服务器,他们做同样的事情,监听和接受套接字,数一下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <sys/resource.h>
#define IP_ADDRESS "0.0.0.0"
#define PORT 20004
int main()
{
// get, set and check RLIMIT_NOFILE
struct rlimit res;
getrlimit(RLIMIT_NOFILE, &res);
printf("%ld %ld\n", res.rlim_cur, res.rlim_max);
res.rlim_cur = res.rlim_max - 1;
int rset = setrlimit(RLIMIT_NOFILE, &res);
printf("Result : %d\n", rset);
getrlimit(RLIMIT_NOFILE, &res);
printf("%ld %ld\n", res.rlim_cur, res.rlim_max);
int sock;
struct sockaddr_in addr;
int yes = 1;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Create Socket Failed::%d\n", errno);
return -1;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
printf("Set Socket Opt Failed::%d\n", errno);
return -1;
}
memset(addr.sin_zero, 0x00, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr( IP_ADDRESS );
addr.sin_port = htons(PORT);
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
printf("Bind Error::%d\n", errno);
return -1;
}
if(listen(sock, 5) == -1)
{
printf("Listen Error::%d\n", errno);
return -1;
}
int n = 1;
while(1) {
int cli_sock = accept(sock, NULL, NULL);
if(cli_sock != -1) {
printf("current connect : %d\n", n);
n++;
} else {
printf("Accept Failed");
break;
}
}
}
import socket
import resource
(_, hard) = resource.getrlimit(resource.RLIMIT_NOFILE)
resource.setrlimit(resource.RLIMIT_NOFILE, (hard - 1, hard))
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('localhost', 20004)
server.bind(server_address)
server.listen(5)
l = []
while(1):
try:
s = server.accept()
except Exception as e:
print(e)
break
else:
l.append(s)
print("current connection : ", len(l))
这是测试客户端,只需创建客户端套接字并连接并计数
import socket
TEST_PORT = 20004
l = []
while(1):
try:
fd = socket.socket()
fd.connect(("0.0.0.0", TEST_PORT))
except Exception as e:
print(e)
break
else:
l.append(fd)
print(len(l))
print(len(l))
所有这些代码我都在普通用户模式下运行,而不是 root 用户我的 CPU 是 i5 6200U @ 2.3Ghz,RAM 是 8GB