How to send messages to a child process

R

Ross

How do you send messages to a child process from inside Java?

I'm running a process by first getting a Runtime from
Runtime.getRuntime();

I then exec a process using Runtime.exec( String [] );

I then get the OutputStream to send info to the process using
Process.getOutputStream();

I then send lines of text to the OutputStream by sending blocks of
bytes. These strings are terminated with newlines.

At the other end (c++ program), I'm using cin to read from standard
output.

But, it seems, whatever I do, the data doesn't get through to the c++
program unless I close the outputstream. Which means that I have to
spark a new process for each command. Which doesn't work. I need to be
sending a continual stream of realtime commands to the c++ program.
How do I do this? Surely there is a way?
 
R

Ross

I tried using read( 0, _, _ ) in the C++ program instead of using
getline on cin, no improvement. Data still gets stuck between the Java
parent process, and the c++ child process.

Any ideas?
 
N

Nigel Wade

I tried using read( 0, _, _ ) in the C++ program instead of using
getline on cin, no improvement. Data still gets stuck between the Java
parent process, and the c++ child process.

Any ideas?

Have you tried flushing the stream after each write?

Are you reading any response that the C++ program may return in a
different thread, or otherwise ensuring that the C++ program doesn't
block on output?
 
R

Ross

Odd. The documentation for OutputStream says that the flush method
does nothing. http://download.oracle.com/javase/1.4.2/docs/api/java/io/OutputStream.html#flush()

I thought I'd checked whether flush() solves the problem, and it
didn't. After you both recommended flush(), I gave it a second try. I
wrote new trial Java and this time an external c program, both
included below. Now it's working. Messages get sent to the c program
and written to output.txt continuously, while without os.flush();,
they all arrive only when the os is closed. I don't know if this is
because I'm currently working on Linux at home rather than Mac at
work, but I'll find out tomorrow.

So, at the moment, this does appears solved. Thanks. I hope :)

// Test.java

import java.io.*;

public class Test
{
public static void main( String args[] ) throws Exception
{
Runtime r = Runtime.getRuntime();

Process p = r.exec( new String[] { "./test" } );

OutputStream os = p.getOutputStream();

for ( int index = 0; index < 100; index++ )
{
String message = "Message #" + (index+1) + "\n";
System.out.println( "Java Program sending: " + message );
os.write( message.getBytes() );
os.flush();

Thread.sleep( 500 );
}

os.close();

p.waitFor();

}
}









// test.c

#include <stdio.h>
#include <string.h>

int main( int argc, char *argv[] )
{
char buffer[1024];
int outFD;

outFD = creat( "output.txt", 0600 );

while( fgets( buffer, 1024, stdin ))
{
write( outFD, buffer, strlen( buffer ));
}

close( outFD );
}
 
R

Ross

This is all working now, both on Linux and Mac. So, problem
convincingly solved. I thought that I had found an old thread saying
that flush didn't work, and when a quick experiment suggested that it
didn't (presumably due to some other bug), didn't try it again. Thanks
muchly.

The Process object gives me a BufferedOutputStream which inherits from
FilteredOutputStream. And flush() works on that fine as you say.
 
R

Roedy Green

I tried using read( 0, _, _ ) in the C++ program instead of using
getline on cin, no improvement. Data still gets stuck between the Java
parent process, and the c++ child process.

The tricks are documented at http://mindprod.com/jgloss/exec.html

The usual problem is you try to pull it off without threads, and it
works to pass a few test chars, then fails when you go into
production. The other common problem is failing to use flush().
 
R

Roedy Green

I tried using read( 0, _, _ ) in the C++ program instead of using
getline on cin, no improvement. Data still gets stuck between the Java
parent process, and the c++ child process.

The tricks are documented at http://mindprod.com/jgloss/exec.html

The usual problem is you try to pull it off without threads, and it
works to pass a few test chars, then fails when you go into
production. The other common problem is failing to use flush().
 
R

Roedy Green

I tried using read( 0, _, _ ) in the C++ program instead of using
getline on cin, no improvement. Data still gets stuck between the Java
parent process, and the c++ child process.

The tricks are documented at http://mindprod.com/jgloss/exec.html

The usual problem is you try to pull it off without threads, and it
works to pass a few test chars, then fails when you go into
production. The other common problem is failing to use flush().
 
R

Roedy Green

I tried using read( 0, _, _ ) in the C++ program instead of using
getline on cin, no improvement. Data still gets stuck between the Java
parent process, and the c++ child process.

The tricks are documented at http://mindprod.com/jgloss/exec.html

The usual problem is you try to pull it off without threads, and it
works to pass a few test chars, then fails when you go into
production. The other common problem is failing to use flush().
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top