views:

829

answers:

2

I saw some similar, but not-quite-what-i-need threads.

I have a server, which will basically take input from a client, client A, and forward it, byte for byte, to another client, client B.

I'd like to connect my inputstream of client A with my output stream of client B. Is that possible? What are ways to do that?

Also, these clients are sending each other messages, which are somewhat time sensitive, so buffering won't do. I do not want a buffer of say 500 and a client sends 499 bytes and then my server holds off on forwarding the 500 bytes because it hasn't received the last byte to fill the buffer.

Right now, I am parsing each message to find its length, then reading length bytes, then forwarding them. I figured (and tested) this would be better than reading a byte and forwarding a byte over and over because that would be very slow. I also did not want to use a buffer or a timer for the reason I stated in my last paragraph — I do not want messages waiting a really long time to get through simply because the buffer isn't full.

What's a good way to do this?

+7  A: 

Just because you use a buffer doesn't mean the stream has to fill that buffer. In other words, this should be okay:

public static void copyStream(InputStream input, OutputStream output)
    throws IOException
{
    byte[] buffer = new byte[1024]; // Adjust if you want
    int bytesRead;
    while ((bytesRead = input.read(buffer)) != -1)
    {
        output.write(buffer, 0, bytesRead);
    }
}

That should work fine - basically the read call will block until there's some data available, but it won't wait until it's all available to fill the buffer. (I suppose it could, and I believe FileInputStream usually will fill the buffer, but a stream attached to a socket is more likely to give you the data immediately.)

I think it's worth at least trying this simple solution first.

Jon Skeet
Yes, I think this clears things up. I think I was getting confused with readFully() which does require the buffer to fill.
jbu
I have tried your code and I also tried reading message by message by reading the message's length then doing a byte[] buf = length; inputstream.read(buf)....the latter method was faster, and I'm not sure why. It seems to execute more lines of code yet it's faster. Almost 2x as fast.
jbu
Also, since my server has multiple sources and a single sink, I think I have to read *messages* within the multiple sources because simply reading and forwarding buffers may interleave messages between clients and scramble them.
jbu
+2  A: 

PipedInputStream, PipedOutputStream

camickr
These two classes shouldn't be used within the same thread.
deamon