2

Given we have a socket connection (lets call it c1) where we accept messages, and we have N other socket connections we are about write the exact same message, to determine which connection we want it to write to we only need to read the first few bytes from c1, but the remaining of the bytes on the socket needs not to be loaded to java heap, just to be written to c2...

So in nutshell what we want to do is. we got event that we have bytes to read on c1 we read the first few bytes and determine that we know that we want to redirect this to c2. We take those first few bytes we already took from c1 write it to c2 and now we want to tell the system to write next N bytes from c1 to c2 directly (instead of c1 -> java heap -> c2).

Is there any means to do this in java?


Update:

Although the answer is to the point, if you are building something like this ( even not only for multiplexing but some little business logic ), I highly recommend you to go with ZeroMQ.

user3666197
  • 1
  • 6
  • 50
  • 92
vach
  • 10,571
  • 12
  • 68
  • 106
  • This is not likely to be doable and even less likely to be a useful optimization. – Louis Wasserman Aug 17 '17 at 02:11
  • 1
    I must disagree sir, the application is like a node in a transport layer of similar nodes, it gets many messages of variable size very frequently and it needs to pass them to correct next node (and multiplex when necessary)... I have measured and i can see that it waists a lot of time on reading and writing of full messages where it just needs first 8 bytes from each message and everything else is OS level work... – vach Aug 17 '17 at 02:18
  • look at this, this is similar to what i want to do except i dont care for files i have sockets ... https://www.ibm.com/developerworks/library/j-zerocopy/ – vach Aug 17 '17 at 02:19
  • Can't you just send the first few bytes from the sender and have the receiver return a socket object to the sender to perform the whole sending? – user681574 Aug 17 '17 at 02:57
  • no, the whole purpose of this is to have a cluster of nodes that know how to deliver to the right place without sender bothering to do custom logic... and handle multiplexing... – vach Aug 17 '17 at 04:10
  • 1
    ZeroMQ was invented for things like this. – bazza Aug 17 '17 at 06:00
  • 1
    @user681574 That suggestion doesn't even make sense. You can't pass sockets over sockets. – user207421 Aug 26 '17 at 00:52
  • It sounds like this isn't what he's trying to do, but an object defining a socket can be serialized and passed over a socket. If the receiver knows how to create the next socket and you'd rather not actually pass the whole message to the receiver, this makes sense. – user681574 Aug 26 '17 at 19:13
  • i'll be more specific, when we get our nio selector indicating that we have data on the system level buffer B1, we will ask specifically 8 bytes to be loaded to java buffer, after that we will know the rest N bytes need to go to B2 and we just need to do this the most efficient way.. even if this is not java, say we are doing C++ is there a way to tell the OS to pass data from buffer to buffer without loading into application memory? if such a thing exists on linux then the worst case is we will do a JNI call (if jvm does not support that call...) but if OS doesnt have this i'm wasting time... – vach Aug 27 '17 at 03:28
  • So basically the question is does Linux allow to pass N bytes from socket buffer A to socket buffer B (we can safely assume that we are on linux, and that no one else is reading or writing to A and B) – vach Aug 27 '17 at 03:35
  • @user681574 You mean a target IP address and port? That's not a socket. – user207421 Aug 27 '17 at 04:13
  • also opened a more specific question on superuser https://superuser.com/questions/1244732/linux-to-transmit-n-bytes-from-socket-buffer-a-to-b – vach Aug 27 '17 at 04:23

1 Answers1

5

Say we are doing C++ is there a way to tell the OS to pass data from buffer to buffer without loading into application memory?

So basically the question is does Linux allow to pass N bytes from socket buffer A to socket buffer B (we can safely assume that we are on linux, and that no one else is reading or writing to A and B)

It may be possible to do this with the Linux "sendfile" syscall.

Reference:

However, this is not supported by the Java I/O class libraries.

UPDATE - Apparently it is supported; see the FileChannel::transferTo method. See the answer to FileChannel zero-copy transferTo fails to copy bytes to SocketChannel for an example that shows this being used with a socket. However, it is not clear if it can be used for socket to socket copies.

UPDATE 2 - Based on the answers to Using Java to perform Zero Copy data transfers between two or more sockets, I think the answer may be: "No it can't". Yet.

UPDATE 3 - Here's the RFE - https://bugs.openjdk.java.net/browse/JDK-6653061

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • i never worked on kernel level so one quick question is the file descriptor is some abstraction that can be used over sockets or its very specific to file system? – vach Aug 27 '17 at 04:29
  • I believe the sendfile is used by the .transferTo method described in https://www.ibm.com/developerworks/library/j-zerocopy/ so it is actually supported (but for files not sockets) – vach Aug 27 '17 at 04:35
  • 3
    A file descriptor (or "fd") is an abstraction that is a "handle" for an open file, socket, pipe or device. If you read the **complete** linked manual entry that I sent you, it is clear that `sendfile` is intended to work for sockets. – Stephen C Aug 27 '17 at 04:39
  • The RFE you cited is only for socket-to-FileChannel transfers, and despite its title it seems to concern implementation, not new APIs. I believe it would be problematic to provide a `sendfile()` wrapper on Windows at the Channel level, as Winsock is kind of bolted onto the side of the WinAPI, with its own socket handles that aren't first-class citizens of the WinAPI. – user207421 Aug 27 '17 at 05:55
  • That could be the real reason that why they (Oracle) haven't addressed this. Anyhow, this RFE is definitely relevant to the problem. – Stephen C Aug 27 '17 at 06:37