我有一个我接受的非阻塞连接套接字:
我有一个非阻塞套接字连接,在收到数据包后,我尝试使用 recv 读取更多数据。
struct sockaddr accepted_address;
socklen_t accepted_address_size = sizeof(accepted_address);
int fd = accept(server_fd, &accepted_address, &accepted_address_size);
make_nonblocking(fd);
... // wait when socket is ready to give me data
char buffer[BUF_SIZE];
int used = 0;
while (true) {
int bytes_received = recv(fd, buffer, BUF_SIZE, 0);
if (bytes_received > 0) { /* OK */ }
else if (bytes_received < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* Should wait for more data, BUT I WILL WAIT INDEFINITELY!!! */
} else {
/* Handle error */
}
} else {
/* EOF, OK, Process received data */
}
}
Run Code Online (Sandbox Code Playgroud)
errno == EAGAIN当第一个 recv 调用检索整个消息,但后续调用导致,导致无限期等待更多永远不会到达的数据时,就会出现问题。
根据这个答案, 这种行为是预期的。
我的问题是: 如果第二次调用 recv 不会给我 EOF 而是返回 EAGAIN,让我无限期地等待,我如何可靠地确定我已收到整个消息?
我如何可靠地确定我已收到完整的消息......
TCP没有消息的概念,它只是一个字节流。这意味着要确定消息的结尾,您需要首先根据您正在实现的应用程序协议了解消息是什么,例如以 结尾的行\n、固定大小的消息或以其大小为前缀的某些有效负载。基于此,您可以检查到目前为止收到的数据是否仅代表消息的一部分、完整消息,甚至不止一条消息。
| 归档时间: |
|
| 查看次数: |
71 次 |
| 最近记录: |