我在我的机器上通过创建新连接直到失败来测试它。在我的机器上,新的connect()
/ accept()
请求在接近700个套接字连接(SOCK_STREAM)时失败*;在客户端/服务器上,分别在环回IP地址上。但是,到目前为止,accept()返回的套接字文件描述符始终绑定到与侦听套接字相同的端口。
我的问题是 - 如果所有机器都出现这种情况,那么为什么accept()
通过创建仅与侦听套接字绑定到同一端口的连接套接字来限制连接?如果新套接字绑定到随机端口(如connect()
那样),服务器可以连接的连接数量是否会大大增加?
另外,为什么accept(sock_fd, NULL, NULL)
失败了“EFAULT - addr参数不在用户地址空间的可写部分。”经过近700次同一次调用的成功迭代后?
同样,为什么connect()
失败,“EFAULT - 套接字结构地址在用户的地址空间之外。”经过近700次同一次调用的成功迭代后?
* EFAULT - 错误地址(在accept()/ connect()之后)。
答案 0 :(得分:2)
当您正在侦听时,所有连接将在连接的接受端具有相同的端口(最初用作标识符以建立连接)。
如果未使用bind()定义连接部分的本地端口号,则可以是任何内容。对于localhost设备,在某些操作系统上可能会非常快速地回收这些数字,因为实际上不需要TCP的延迟状态。
当涉及同时拥有多个连接时,可能的连接数量受到每个进程的操作系统资源的限制。对于Unix / Linux,可以调整此限制,如果使用select(),建议不要使FD的数量高于默认值,因为FDSET的libc大小通常与每个进程可用的默认文件描述符数相匹配。围绕这个的一个技巧是创建套接字,分出子进程并让子进程调用accept()。然后每个孩子可以有很多连接(apache和squid使用这种模型),增加了同一服务器端口上可能的连接总量。
答案 1 :(得分:1)
为什么accept()通过创建仅与侦听套接字绑定到同一端口的连接套接字来限制连接?如果新的套接字被绑定到随机端口(如connect()那么),服务器可以增加的连接数量是不是很大?
它没有施加任何限制。连接的TCP套接字"地址"应该被视为四个参数:srcip,srcport,dstip,dstport。因此,绝对不需要将accept()
'套接字绑定到随机端口。
另外,为什么accept(sock_fd,NULL,NULL)失败并且" EFAULT - addr参数不在用户地址空间的可写部分中。"经过近700次同一次呼叫的成功迭代后?
嗯,关于操作系统内部问题。任何用户进程的资源量可能(并且应该)受到限制。阅读您的操作系统开发人员手册等。