在我的系统上输入man recv(),我得到:
ssize_t
recv(int socket, void *buffer, size_t length, int flags);
…
RETURN VALUES
These calls return the number of bytes received, or -1 if an error occurred.注意,length是无符号类型size_t,函数的结果是一个带符号的ssize_t。
如果为length传递了一个大于SSIZE_MAX的值,那么recv()填满buffer指向的内存并返回-1以外的负值的情况有多理论?是否有允许超长消息的套接字类型(Unix域?)?那MSG_WAITALL呢?
发布于 2013-06-21 04:56:36
下面是关于ssize_t (摘自B.2.12 Data Types)的POSIX2008基本原理:
ssize_t
这是size_t的有符号类比。其措辞是,实现可以选择使用更长的类型,也可以简单地使用作为size_t基础的类型的有符号版本。所有返回ssize_t (read()和write())的函数都将输入超过{SSIZE_MAX}的结果描述为“实现定义的”。
实际上,这并不完全正确,因为包括recv在内的返回ssize_t的套接字函数没有提到任何超过SSIZE_MAX的输入。所以我认为这是一个意图的声明,暗示recv中缺少的措辞是一个错误,有一天可能会纠正。
简而言之,如果您想要编写可移植的代码,则需要确保I/O段不超过SSIZE_MAX。此外,SSIZE_MAX可能会小到32767。所以可移植的代码不应该假设它可能更大。
然而,并不是每个人都那么关心可移植性。您可能对代码在其上运行的实现有所了解。Posix继续:
认识到,某些实现可能具有小于size_t的It。一致性应用程序将受到约束,不能以大于{SSIZE_MAX}的片段执行I/O,但如果该实现提供扩展范围,则使用扩展的一致性应用程序将能够使用整个范围,同时仍具有单个类型兼容接口。
Posix保证recv返回的唯一值是-1、0或接收到的字节数。根据上面的措辞,符合的实现可以将大于SSIZE_MAX但小于或等于2*SSIZE_MAX的值映射到-1以外的负整数上。(如何做到这一点留给感兴趣的读者作为练习:)。但是,据我所知,Linux并没有记录任何这样的扩展。
https://stackoverflow.com/questions/17221856
复制相似问题