Java 从套接字到套接字的零分配副本

Java 从套接字到套接字的零分配副本,java,performance,sockets,nio,low-latency,Java,Performance,Sockets,Nio,Low Latency,假设我们有一个接受消息的套接字连接(我们称之为c1), 我们还有N个其他的套接字连接我们要写的是完全相同的消息, 要确定要将其写入哪个连接,只需从c1读取前几个字节,但套接字上剩余的字节不需要加载到java堆,只需写入c2 简而言之,我们要做的是。 我们得到了一个事件,我们有字节可以读取c1 我们读取前几个字节并确定我们知道要将其重定向到c2。 我们将已经从c1中获取的前几个字节写入c2,现在我们想告诉系统直接将c1中的下N个字节写入c2(而不是c1->java heap->c2) 在java中

假设我们有一个接受消息的套接字连接(我们称之为
c1
), 我们还有N个其他的套接字连接我们要写的是完全相同的消息, 要确定要将其写入哪个连接,只需从
c1
读取前几个字节,但套接字上剩余的字节不需要加载到java堆,只需写入
c2

简而言之,我们要做的是。 我们得到了一个事件,我们有字节可以读取
c1
我们读取前几个字节并确定我们知道要将其重定向到
c2
。 我们将已经从
c1
中获取的前几个字节写入
c2
,现在我们想告诉系统直接将
c1
中的下N个字节写入
c2
(而不是c1->java heap->c2)

在java中有什么方法可以做到这一点吗


更新: 尽管答案是中肯的,但如果您正在构建类似的东西(甚至不仅仅是为了多路复用,还有一些小的业务逻辑),我强烈建议您使用ZeroMQ

< P >我们说C++是有办法告诉OS把数据从缓冲区传递到缓冲区而不加载到应用程序内存中吗? 所以基本上,问题是Linux是否允许将N个字节从套接字缓冲区A传递到套接字缓冲区B(我们可以安全地假设我们在Linux上,并且没有其他人在读或写A和B)

可以通过Linux“sendfile”系统调用实现这一点

参考:

但是,Java I/O类库不支持这一点

更新-显然它是受支持的;请参阅
FileChannel::transferTo
方法。请参阅的答案,以获取一个示例,该示例显示此选项与套接字一起使用。但是,目前尚不清楚它是否可以用于套接字到套接字的复制

更新2-根据对的回答,我认为答案可能是:“不行”。然而


更新3-以下是RFE-

这不太可能是可行的,甚至不太可能是有用的优化。我一定不同意,先生,应用程序就像是类似节点的传输层中的一个节点,它经常收到许多大小可变的消息,需要将它们传递给下一个节点(必要时进行多路复用)…我已经测量过了,我可以看到它在读写完整消息上花费了很多时间,而它只需要每条消息的前8个字节,其他一切都是操作系统级的工作…看看这个,这与我想做的类似,只是我不关心我有套接字的文件…ZeroMQ是为类似的事情而发明的。@user681574 Tha建议根本没有意义。你不能通过套接字传递套接字。我从来没有在内核级别工作过,所以一个简单的问题是文件描述符是可以通过套接字使用的抽象还是它非常特定于文件系统?我相信sendfile是由中描述的.transferTo方法使用的,所以它实际上是受支持的(但对于文件而不是套接字)文件描述符(或“fd”)是一个抽象,是一个“句柄”对于打开的文件、套接字、管道或设备。如果您阅读了我发送给您的完整链接手册条目,很明显,
sendfile
用于套接字。您引用的RFE仅用于套接字到文件通道的传输,尽管它的标题似乎与实现有关,而不是与新API有关。我相信,使用它会有问题在Windows上提供一个通道级的
sendfile()
包装,因为Winsock有点固定在WinAPI的侧面,它自己的套接字句柄不是WinAPI的一等公民。这可能是他们(Oracle)没有解决这个问题的真正原因。无论如何,这个RFE肯定与问题有关。