Reputation: 275
I am having stability issues using a named pipe for communication between a C# and Java app.
Here is the code that sets up the named pipe in C# and reads lines of XML strings.
try
{
NamedPipeServerStream inStream = new NamedPipeServerStream(inName, PipeDirection.In);
inStream.WaitForConnection();
reader = new StreamReader(inStream);
while (!Stopped && !reader.EndOfStream)
{
string xml = reader.ReadLine();
processXml(xml);
}
}
catch (Exception e)
{
log.Error("Error in receiver", e);
}
finally
{
log.Info("Receiver ended");
}
And here is the connection and write code in Java
public void connect() throws TransportUnavailableException
{
try
{
File inPipe = new File(inName);
os = new FileOutputStream(inPipe);
// Uses JAXB for XML serialization
marshaller = context.createMarshaller();
}
catch (FileNotFoundException e)
{
throw new TransportUnavailableException("Named pipe not found: " + inName);
}
}
public void send(Message message)
{
marshaller.marshal(message, os);
os.write('\n');
os.flush();
}
Everything works fine normally. But many users are reporting crashes. I don't see any exceptions in logs that suggest a reason for the pipe dying. I just see that the receiving thread in C# ends (i.e. 'Receiver ended' in the logs) and after this I get an IO exception on the next attempted send from Java with a message 'The handle is invalid'. This seems to happen randomly, but usually within the 1st minute or 2 after the connection was established. The pipe ending message also happens when the application is not doing anything, it could have been minutes since the last user operation. Then it could be a few more minutes before the next write is attempted from Java.
All reasons for my app to bring down the pipe on purpose (e.g. a crash elsewhere in system) are logged and I never see that as a reason for the pipe ended, I just get the message that the reader has given up reading.
Any help/suggestion appreciated Thanks!
Upvotes: 2
Views: 2200
Reputation: 311008
Your server side code only processes one connection, then it exits when it reads to EOS. You need to create the named pipe, loop accepting connections, and spin up a new thread to handle each connection. You also need to close each connection when you're finished with it.
However I would use TCP rather than named pipes for this, for several reasons.
Upvotes: 1