您可能正在达到内核缓冲区限制。您可能可以在接收器上增加 SO_RCVBUF 并且它会按预期工作:SIOCINQ 最终将返回未读数据的完整大小。
但是您不应该这样做以确保正常运行。只有在您想调整性能时才应该弄乱缓冲区。
您应该重构代码,这样您就不必询问内核有多少字节可用。只需阅读到一个合理的限制(如 4096)并处理一个应用程序级消息被分解为多个部分。如果您需要消息长度/边界,那么您必须自己在 TCP 之上实现它们。
这是一些愚蠢的代码来读取带有长度标头的消息:
int ret, len = 0, have_read;
have_read = 0;
while (have_read < sizeof(len)) {
// This will likely always return sizeof(len) the first time.
ret = read(fd, ((char*)&len) + have_read, sizeof(len) - have_read);
if (ret <= 0) {
// Handle error.
}
have_read += ret;
}
char* buf = malloc(len);
if (!buf) {
// Handle error.
}
have_read = 0;
while (have_read < len) {
ret = read(fd, buf + have_read, len - have_read);
if (ret <= 0) {
// Handle error.
}
have_read += ret;
}
// Handle message in buf.