当我可以读取套接字缓冲区而不实际读取它时,有一个peek选项(以了解可用于后续读取的字节数)。fcntl 调用有这样的选择。
我想知道是否有一种方法可以在不将数据从套接字复制到应用程序缓冲区的情况下实际读取套接字缓冲区?因此,如果您愿意,可以迷惑内核:目的是在设计诸如在 Web 服务器上创建负载的工具时,不要浪费时间复制实际数据:我们需要正确进行 tcp 通信,但我们不需要数据已收到。请问有什么建议吗?
man tcp
是你在 Linux 系统上的朋友:
从 2.4 版开始,Linux 支持在 recv(2)(和 recvmsg(2))的 flags 参数中使用 MSG_TRUNC。此标志导致接收到的数据字节被丢弃,而不是在调用者提供的缓冲区中传回。
因此,您可以(在 TCP 套接字上)例如,
int n = recv(sock_fd, buf, buf_size, MSG_TRUNC);
buf_size
这将消耗来自套接字描述符的最多字节,sock_fd
而不会实际将它们复制到缓冲区。
使用带有标志的recv系统调用。MSG_PEEK
这个答案本来是要发表评论的,但恕我直言,评论太大了。
是的,使用splice(2)
性能会提高(如果这当然是你的瓶颈)(你确定这是你的瓶颈吗?)。虽然splice(2)
是 Linux 特定的系统调用,但不应在可移植程序中使用。因此,让我们看看您的一些选择:
splice(2)
非常高效但不便携。sendfile(2)
但原型因 UNIX 系统而异。IMO 你应该使用 libevent,它提供了一个很好的跨平台可移植的接口。
浏览 Kira 提出的提示让我了解了带有 /dev/null 目标的 splice() 调用。现在应该做:-)