在Linux上,select()如何确定何时可以在不阻塞的情况下写入TCP/IP连接?

在Linux上,select()如何确定何时可以在不阻塞的情况下写入TCP/IP连接?,c,linux,sockets,select,tcp,C,Linux,Sockets,Select,Tcp,从select()的手册页: 将监视writefds中的写入,以查看写入是否不会阻塞 对于与TCP/IP连接关联的文件描述符,select()函数如何确定何时可以在不阻塞的情况下写入连接?我的问题的另一种表述方式是,select()返回表示可以在不阻塞的情况下写入文件描述符的条件是什么 我假设如果发送缓冲区已满,select()将不会返回fd_集中的fd。如果是真的,这是唯一的考虑因素吗?我可以想象许多可能的标准来确定写操作是否应该阻塞,因此我有兴趣具体了解这在Linux上是如何工作的。当发送缓

从select()的手册页:

将监视writefds中的写入,以查看写入是否不会阻塞

对于与TCP/IP连接关联的文件描述符,select()函数如何确定何时可以在不阻塞的情况下写入连接?我的问题的另一种表述方式是,select()返回表示可以在不阻塞的情况下写入文件描述符的条件是什么


我假设如果发送缓冲区已满,select()将不会返回fd_集中的fd。如果是真的,这是唯一的考虑因素吗?我可以想象许多可能的标准来确定写操作是否应该阻塞,因此我有兴趣具体了解这在Linux上是如何工作的。

当发送缓冲区中有空间时,它将指示FD是可写的。没有其他考虑


连接时,这包括连接完成的情况,因为此时发送缓冲区已有效分配。

如果您写入数据,它们不会立即传输到对等方,但会首先存储在套接字缓冲区中。然后内核将数据从套接字缓冲区中取出并传输它们。根据传输协议的不同,数据可能以尽可能快的速度传输(UDP),或者存在某种流控制,使数据保留在发送方,直到发送方确认为止(TCP)。如果有太多未确认的数据,它将停止处理套接字缓冲区内的数据,然后套接字缓冲区将开始填满。一旦缓冲区中没有更多的空间,写入将被阻塞。一旦套接字缓冲区中再次有足够的空间,就可以再次写入,这将在select中发出信号。

几点澄清:这不是“太多未确认的数据”,而是“对等方的接收窗口已满”。此外,如果(a)套接字未配置为非阻塞,并且(b)写入的大小超过可用的缓冲区空间,“缓冲区写入”将被阻塞。@BrianWhite:是,我试图让它更接近流控制的基本思想,因为在提到接收窗口时,有必要更深入地描述TCP流控制方式。但是我看不到TCP的(b):因为TCP是一种流协议,而不是像UDP那样的数据报,所以它将尽可能地将所有内容写入套接字缓冲区,并只返回写入的大小。因此,如果缓冲区中有200个字节可用,则在尝试写入1000个字节时,它不会阻塞,而是写入200个字节并将其作为写入的数字返回。如果缓冲区空间已满,则
O_NONBLOCK
套接字将返回200个1000字节,就像它将返回0一样。没有该选项(默认设置)的套接字将等待所有内容都被本地缓冲区接受。@BrianWhite:你说得对。谢谢你指出这种行为。