Question

Trying out different interprocess communication methods.

I have a C# application that spawns a ruby process and redirects the ruby process' stdin and stdout so that C# app can send instructions to the ruby process and the ruby process can send some stuff back.

Ruby:

cmd = STDIN.read
p "Test command received!" if cmd.downcase == "test"

C#

static void Main(string[] args)
{
  ProcessStartInfo procInfo = new ProcessStartInfo("ruby");
  procInfo.Arguments = "stdinTest.rb";
  procInfo.UseShellExecute = false;
  procInfo.RedirectStandardInput = true;
  procInfo.RedirectStandardOutput = true;

  proc = new Process();
  proc.StartInfo = procInfo;
  proc.Start();
  proc.StandardInput.Write("test");
  proc.StandardInput.Close();

  Console.WriteLine(proc.StandardOutput.ReadLine());
}

This assumes that Ruby is located on the sys path and the ruby script is in the same folder as the C# app.

When I run the C# app, it prints out "Test command received!" as expected.

However, one thing that is questionable is the fact that I'm closing the process' stdin...which means I can't write to it anymore.

If I remove the close, it just hangs. Presumably because Ruby's not getting an expected character that tells it to stop reading.

If I use flush, it doesn't make a difference.

What is the problem with this exchange?
Is there a different way for C# to send data to ruby's STDIN?
Should Ruby be reading from STDIN a different way?

Was it helpful?

Solution

STDIN is a stream and STDIN.read is trying to read up to the end of the stream. Send length of your data first and use read with length:

Packet: 0008ABCDEFGH (in real life you should use binary length)

length = STDIN.read(4).to_i
data = STDIN.read(length)

Then you don't have to close it and can send another packet(s).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top