来自官方POSIX参考文献:
当使用
O_NONBLOCK
清除调用输出函数时,描述符将被视为准备好写入,无论函数是否成功传输数据。
正如您所看到的,它实际上并没有提到任何大小,或者写入是否成功,只是说您可以在不阻塞的情况下写入套接字。
因此,答案是没有最小保证大小。
我认为在POSIX层上,你无法对此进行任何控制。send()将接受你传递到TCP/IP堆栈实现的内部缓冲区中的任何内容。接下来会发生什么,你可以使用相同的select()调用来监视。
如果你问的是一个数据包可以容纳多大的大小,那就是MTU(但这个假设也应该小心谨慎地使用,因为涉及到分片和重组数据包的问题)。
更新:
我会在这里回答你的评论。不,你不应该担心分片。把它留给TCP/IP堆栈处理。有很多理由你不应该这样做。例如,你的应用程序工作在OSI模型的应用层(虽然我认为OSI模型在大多数情况下都是一件坏事,但它确实适用于这个例子)。从这个层面上,你试图影响位于更低层的逻辑功能/属性(会话/传输)。你不应该这样做。像send()、recv()这样的POSIX调用旨在为你的应用程序提供指示底层层次传递一定量的数据的能力,并且你有一种监视命令执行的方法(select()),这就是你需要做的全部。更低层次的处理应该根据操作系统网络设置等,尽最大努力以最优化的方式传递你指示它们传递的数据。
更新2:以上大部分内容主要考虑非阻塞套接字。很抱歉忘了提到这一点,我已经很久没有在我的项目中使用阻塞套接字了。如果您的套接字是阻塞的,我仍然会考虑一次性传递所有内容,然后在另一个线程中等待操作结果,因为尝试优化这个可能会导致非常依赖于操作系统/驱动程序的代码。
当 select() 指示
一个套接字可写时,保证您可以传输至少一个字节而不会遇到EWOULDBLOCK
或EAGAIN
的错误。但是,并不意味着您不会遇到其他错误 :-)