Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

InputStream to multiple Readers  RSS feed

 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a socket server that gets a socket and does this:

In response to some comand that comes in over this stream, I want to temporarily hook the socket up to another reader.

Now, ya can't have two consumers hooked up to one provider. Once one consumes the content, the other will get nothing. Right? After the 2nd assignment statement above, all input goes to mTempInput.
How do I disconnect mTempInput and restore the flow to mReader?
Maybe I should give up on this swapping idea and open another socket for the temporary thing to use? (Would require mod to the client, but I can do that, too.)
 
Leslie Chaim
Ranch Hand
Posts: 336
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[B]
In response to some comand that comes in over this stream, I want to temporarily hook the socket up to another reader.

[/B]
I assume that based on some command you need to get directly at the 'raw' stream (and perhaps chaining it up with something else such as ObjectInputStream)
Here's a simple thought, when you create your mReader don't chain them up. Just create intermediary variables like this:

Then if some command is read from the mReader then you can delve into the underlying stream and the is variable (or reference ).
There may be some issues with flushing the buffers but I think that all has to do with your protocol.
Please correct me if I am wrong.
Regards,
Leslie
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unfortunately, the BufferedReader will usually read ahead an unknown number of bytes from the underlying stream, for efficiency. There's no easy way to control this. I suppose you might do something with a PushbackInputStream, but it's going to be pretty hard to figure out how many bytes need to be pushed back. I think this approach is probably doomed. This same issue may occur for other reader/writer/input/output streams, not just the buffered ones. It's just that the buffered streams read ahead a lot; other stream may read ahead a little as well. Consult docs carefully to see if it's mentioned.
Really, any solution that mixes text messages and raw bytes in the same stream is going to be pretty challenging to implement unless the protocol is carefully designed to make it as easy as possible. Perhaps your best bet is to look at DataInputStream and DataOutputStream; methods like readUTF() and writeUTF() let you read and write text-like stuff using streams (not readers) because they also use a few extra bytes to signal how long the text will be. Which makes it easier to tell exactly when it ends, and switch to other byte methods as necessary.
Alternately, another approach may be to read everythign you can from the stream into a byte[] array (or alternately a file), and then analyze it however you want. As long as the info is saved somehow after it's read, you have more flxibility to figure out exactly where the text ends and your raw data begins. One approach - loop through the raw bytes looking for newline characters. Once you find a line boundary, you can process everything betweenthe last two boundaries found, converting those bytes to string, and doing whatever else you need to do. When you find the signal to switch over to some other processing for subsequent lines, you should know exactly where the last line ended, and you can go from there.
Another possibility is to communicate exclusively using serialized objects. Text messages can be represented using serialized Strings, and other objects can be represented with whatever class is appropriate. The raw bytes won't be very human-readable, though the text will probably be legible, in between bits of gibberish. But it's a powerful and flxible techique for transmitting arbitrary types of data, as long as both sender and recipient are running Java using the same protocol.
So, before you spend too much time figuring out how to parse this - see if there isn't some way to modify the communications protocol so it's easier to tell the different types of data apart.
[ May 29, 2003: Message edited by: Jim Yingst ]
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The data could be all string, but I suspect that doesn't really help much. Here's what's going on in the program:
  • client sends a command, eg "netstat" or something more interactive
  • server receives command
  • server uses runtime.exec() to start the command
  • server pipes the proc's stdin-stdout-errout to and from the client.
  • client receives and displays output of the command
  • the user of the client can enter data to command prompts
  • when the command ends (a little hard to detect) the server unhooks the pipes.
  • the client sends another command
  • the server receives the command, and so on

  • This is all working pretty well right now, except: After one command ends, the next thing sent from the client appears goes to the little pipe class that I thought I disconnected. But the next line after that from the client is fine. Sigh.
    Buffered readers may be part of the problem. I might try to go a little closer to the socket.
     
    Scotty Sinclair
    Greenhorn
    Posts: 17
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You should be able to do this is you have tighter synchronization between the client & server using acknowledgements for example.
    InputSream is = mSocket.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader mReader = new BufferedReader (isr);
    CommandReader cReader = new CommandReader(mReader);

    //client hs only sent command data
    Command c = cReader.readCommand();
    sendCommandAck(); //notify we have read the command so that the client can send the data
    c.handleInput(mReader); //handle the input
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!