TransmitFile 在管道上工作吗?
TransmitFilewinsock 函数的文档确实说“文件”而不是“文件描述符”,所以答案也许是否定的?如果我无法使用 TransmitFile 通过套接字从管道发送数据,是否可以使用其他一些零复制技术?
The docs for the TransmitFile winsock function do say "file" and not "file descriptor", so maybe the answer is no? If I can't use TransmitFile to send data from a pipe over a socket, is there some other zero-copy technique I can use?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要进行手动零复制传输,您需要以重叠模式打开套接字和文件,并将它们与 IO 完成端口关联。然后,您对文件进行读取,当文件读取完成时,您将已填充的缓冲区传递给套接字上的写入。然后,您可以通过调整套接字上的发送缓冲区大小以防止复制以及在打开文件时选择正确的标志来调整此设置。
请注意,您可能应该使用后续的套接字写入完成来驱动文件读取。也就是说,当旧的读取完成时,不要继续发出新的读取,因为 TCP 堆栈可能会由于 TCP 窗口已满而最终进行流量控制,此时您将使用非分页池作为套接字写入需要越来越长的时间才能完成(请参阅 此处了解更多详细信息)。因此,决定每个连接允许的未完成套接字写入数量,并在达到该数量时限制读取,即从读取完成时读取切换到写入完成时读取...
请注意,这并不像与使用 TransmitFile() 本身一样有效,因为这可以避免内核到用户的转换,从而通知您读取完成并发出写入调用。
回答你问题的第一部分,如果你尝试会发生什么?
To do a manual zero copy transmission you need to open both the socket and the file in overlapped mode and associate them with an IO completion port. You then issue a read on the file and when the file read completes you pass the buffer that was filled to a write on the socket. You can then probably tune this by adjusting the send buffer size on the socket to prevent copying and by selecting the correct flags when you open the file.
Be aware that you should probably use the subsequent socket write completion to drive your file reads. That is, don't keep issuing a new read when the old one completes as the TCP stack will likely end up doing flow control due to the TCP window becoming full and at that point you'll be using up non paged pool as your socket writes take longer and longer to complete (see here for more details). So decide on the number of outstanding socket writes that you'll allow per connection and throttle your reads when that number is reached, that is, switch from read on read completion to read on write completion...
Note that this isn't as effective as using
TransmitFile()
itself as that avoids the kernel to user transitions that occur to notify you of the read completion and to issue the write call.In answer to the first part of your question, what happens if you try?