【问题标题】:UNIX SOCKET - direct write into socket's memory possible?UNIX SOCKET - 可以直接写入套接字的内存吗?
【发布时间】:2013-09-10 15:10:56
【问题描述】:

在我的软件中,我为 IPC 使用 PF_UNIX-socket。

到目前为止,我需要通过malloc 分配一个(预)缓冲区来准备数据,然后再通过write 将数据写入缓冲区。

现在我想知道:

socket-fd 已经有一个缓冲区,例如。 64kb,那么为什么我不能像这样直接准备并将数据写入该缓冲区:

// stupid example-code, don't copy
void *fd_buffer = get_buffer_of_fd(fd)
fd_buffer[0] = 1
fd_buffer[1] = 2
fd_buffer[2] = 3
memcpy(fd_buffer, 5, 5)
...
commit_buffer_of_fd(fd, xbytes); // xBytes is DYNAMIC and not known until this point!!

如果可能的话,我可以省去复制到预缓冲区、从预缓冲区写入套接字甚至分配预缓冲区的往返过程。

有人知道这是否可行吗?

【问题讨论】:

  • 我很确定你想要的东西没有得到任何支持。此外,如果在套接字上复制数据所花费的时间是如此之大,为什么不直接使用共享内存进行通信呢?它会更快、更干净,并且得到实际支持。
  • 非常感谢您的反馈。没什么大不了的,我只是在寻找更好的方法 :-) 因为我在 Android 上,所以遗憾的是没有共享内存的方法。非常感谢!
  • 一些拼接的例子:ogris.de/howtos/splice.html
  • 好提示,谢谢我会分析这个:)

标签: c shared-memory unix-socket


【解决方案1】:

套接字缓冲区归内核所有,你永远不能写入内核空间。永远不能。安全风险太大。

进行零拷贝的唯一方法是使用vmsplice(2),但它不被官方支持用于套接字,不建议用于管道以外的任何东西。

如果您决定使用vmsplice,请记住您必须在页面块sysconf(_SC_PAGESIZE) 中提交您的数据。它也是一个仅限 Linux 的系统调用,不可移植。

【讨论】:

  • 套接字不是管道吗?我认为套接字几乎是splice 的主要理由,例如sendfile.
  • @Duck 管道本质上只是一个带有一定缓冲区的先进先出。套接字具有底层协议,除了通常是双向的之外,它还关联着控制堆栈和其他套接字控制方法。这是一个复杂得多的结构,splice/vmsplice 不是为与套接字一起使用而设计的。
  • 管道、fifos 和套接字都属于通用术语管道。套接字可能有也可能没有底层协议,例如OP 问题的域套接字,实际上只是一个具有套接字语义的内核管理缓冲区。自 2.6.25 起,与 tcp 套接字之间的拼接已经(官方或不)支持 4 或 5 年
猜你喜欢
  • 2011-12-06
  • 2017-07-31
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 1970-01-01
  • 2014-07-07
  • 2011-12-03
  • 1970-01-01
相关资源
最近更新 更多