繁体   English   中英

从c中读取tcp套接字,并在不复制到用户空间的情况下读取数据

[英]reading from tcp socket in c, and chucking data without being copied to user space

有一个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);

这将从套接字描述符sock_fd消耗最多buf_size字节,而不实际将它们复制到缓冲区。

recv系统调用与MSG_PEEK标志一起使用。

这个答案本来是一个评论,但它只是为了评论恕我直言。

是的,使用splice(2)性能会提高(如果这是你的瓶颈)(你确定这是你的瓶颈吗?)。 虽然splice(2)是Linux特定的系统调用,但不应该在便携式程序中使用。 所以,让我们看看你的几个选择:

  1. splice(2)非常高效但不便携。
  2. sendfile(2)系统调用是可移植的,但原型在UNIX系统中各不相同。
  3. 为多个操作系统制作包装功能。
  4. 使用libevent。

IMO你应该使用libevent,它提供了一个可以跨多个平台移植的漂亮界面。

浏览Kira提出的提示,让我了解了使用/ dev / null目标的splice()调用。 现在应该这样做:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM