accept()如何确定返回哪个整数?

accept()如何确定返回哪个整数?,c,sockets,C,Sockets,在Linux系统上使用C套接字库 当我调用accept()时,它总是返回一个整数STDIN为0。通常我的第一个接受电话返回3。之后它们会增加 我在想;accept()如何确定下一个整数?如果在另外两个accept()调用之后,我有3个、4个和5个分配给连接的客户端;当4个断开连接时会发生什么?下一个整数是4还是6 如果有人能解释一下,我肯定会很感激的。它使用了下一个当前未打开的文件描述符,与open()和其他返回文件描述符的系统调用相同dup2()是该模式的一个例外。(例如,文件描述符可能未打开

在Linux系统上使用C套接字库

当我调用
accept()
时,它总是返回一个整数
STDIN
为0。通常我的第一个接受电话返回3。之后它们会增加

我在想;
accept()
如何确定下一个整数?如果在另外两个
accept()
调用之后,我有3个、4个和5个分配给连接的客户端;当4个断开连接时会发生什么?下一个整数是4还是6


如果有人能解释一下,我肯定会很感激的。

它使用了下一个当前未打开的文件描述符,与
open()
和其他返回文件描述符的系统调用相同
dup2()
是该模式的一个例外。(例如,文件描述符可能未打开,但如果它是尚未完全清理的网络连接的一部分,则可能仍然无法重用。)(更新:删除的文本将恢复原始版本的应答。如果文件描述符已关闭,则可供重用。由于TCP/IP中的FIN-WAIT状态,重用套接字地址可能会出现问题,但套接字地址不是文件描述符。)

如果描述符1-5打开,然后关闭4,则下一个类似打开的操作将返回4


可能有一些具有安全意识的系统不是这种模式,但不太可能。一个原因是,有正确的代码用于处理I/O重定向,该代码依赖于关闭标准输入(文件描述符0)和下一个类似打开的操作重用文件描述符;对标准输出重复此操作(文件描述符1).

它将为接受的套接字返回一个文件描述符:

RETURN VALUES
     The call returns -1 on error and the global variable errno is set to
     indicate the error.  If it succeeds, it returns a non-negative integer
     that is a descriptor for the accepted socket.

这将为您提供一个数值,您可以在各种文件操作中使用该数值,这是由幕后决定的。

简单的回答是,不要指望接受以任何预期顺序为您提供整数。无论您认为如果接受,事情会变得多么容易


accept返回的实际上是内核资源的“描述符”,它将把描述符连接到读写、关闭、查找(如果有能力)所需的适当驱动程序。可用描述符的池是有限的,因此当您关闭套接字时,其描述符会返回到池中并可以重新使用。

那么在问题的上下文中是“下一个未打开的文件描述符”4还是6?为了更清楚,我会写“可用的最低值”。如果4是shutdown()如果4在本地关闭(),则下一个open()/accept()/无论什么都将重用它(假设0-3正在使用)。括号内的注释是错误的。如果a
close(fd)
已成功返回,该号码立即可用。将始终使用可用的最低fd号码。POSIX要求这样做,而更改此行为的“安全”修改实际上会使依赖正确和标准行为的一些正确和一致的程序易受攻击。+1一些调用,如
dup()
,用于返回编号最低的可用描述符。我不认为您可以将其用于
accept()
。0,1,2并不总是被“接受”,并且内核在“启动”新进程时不需要分配任何内容(PID 1除外)。它们只是从父级继承的。因此,如果您编写
ls-l/dev/fd/&-
,您将看到0和2与终端断开连接(并且可能被
ls
重新用于读取目录列表).这个答案是错误的。最低可用分配是标准的一部分,在POSIX系统和所有经典Unice上100%可靠。