IPC using Named Pipes, having trouble

Rayanth

Member
Joined
Mar 16, 2006
Messages
9
Programming Experience
3-5
I have a fairly awkward setup here, and IPC via Named Pipes seems to be the best way to solve it. FIrst I'll take a moment to explain my setup:

A 3rd party program generates lines of text in realtime (where they come from doesn't matter).
That 3rd party program has allowed me to write a DLL Plugin to capture those lines of text for my own use.
I am writing a very complex program to use those lines of text for various purposes, which are beyond the scope of the problem.

The problem I have is getting the lines of text from my DLL, to my Program (two seperate projects). The 3rd Party App only recognizes DLL's written in VB.Net.

My initial attempt uses a system of two log files to transfer text back and forth. My DLL opens/writes/closes the temp log file each time a line comes through, and my Program reads the log file on a 2 second timer, copies tis contents to a permanent log file and erases the temp. This is, as I'm sure you can tell, a HUGE amount of overhead. I need this to stay as real-time as possible (no buffering), and the load the DLL is under could be several dozen lines per second. It is possible (and has happened) for the Program to attempt to read the temp log at the same moment the DLL is writing to it - this causes a crash in the main program.... (I can write a 'test' loop to make sure it's readable, but that still may not solve things perfectly)

Anyway, to reduce overhead and speed things up, i'm looking into IPC via Named Pipes. The MSDN example of Named Pipes (after some tweaking of their bugs), works well enough but they don't document very well what they are doing, and the important parts aren't documented at all (namely, what the heck they're doing with the data being transferred, there's two Mod ops on them and the resulting data at the client end is not recognizable, so I can't tell how it came across)

I would like to transfer my data in Strings over the named pipe -- is this possible without converting the string to bytes and back again? I attempted a conversion of string->byte, transfer, byte-> string but the client-side conversion resulted in garbage...

If I could get some help on either transferring via String, or properly converting String to ByteArray and back again, I would greatly appreciate it!
 
The Named Pipes article here looks nice, but the code is in C# http://ivanweb.com/articles/namedpipes/index.cfm

As for String and Byte array here is code:
VB.NET:
Dim str As String = "hello"
Dim bt() As Byte = System.Text.Encoding.Default.GetBytes(str)
MsgBox(System.Text.Encoding.Default.GetString(bt))
 
Ironically, I had found a copy of this article on my own, but it utilizes a class that someone else wrote, to simplify things...

I am using System.Text.ASCIIEncoding.GetBytes() and GetString() to convert back and forth. It seems pipes can only be written in byte mode, so i'm stuck with that.

What I can't figure out is, somewhere either in the client side, or the pipe itself, the data is getting mangled. I have a msgbox set in the server code *right* before it writes the string to the pipe to tell me what it's writing, and confirms that it is a valid string (passing it through GetString in the msgbox call). But when I read it and GetString it on the Client end, I get garbage. Either I'm calling something wrong, or misunderstanding what happens to the data across the pipe...

Is there maybe some other alternative to solve this, that doesn't involved named pipes? I've spent two days trying to get them working and i'm still at square one...
 
I don't know why your string data don't come right through the pipes, could be something with the wrapper you're using. You probably know about the first-4-bytes-is-message-length trick, or it is being handled.

Two other options that can be done natively in .Net without Win32 API code are Remoting (System.RunTime.Remoting) and TCP sockets (System.Net.Sockets). They both also got the benefit that they can be used outside local LAN, which Named Pipes method can not.

As an introduction to TCPlistener and TCPclient classes I have found this article and code example with a client and server quite good: http://www.eggheadcafe.com/articles/20020323.asp
 
Remoting adds a decent amount of overhead when used on local machines, or so I had read somewhere... not sure what the scale of the overhead they were talking about was...

I'm currently looking at using my own file-lock system, while i study on how .NET handles true tcp/ip internet applications, which i have significant experience with. My current plan is to enable the DLL as a TCP server and use a standard port on localhost to communicate the data across... provided this is possible in .NET. TCP/IP has never had significant overhead in my experience, and allows data to be sent in text format, bypassing the need for byte conversion entirely.

I thank you for the help you offered, but it seems named pipes are just incredibly awkward to work with - far too much so to be useful in my application.
 
Using one port for this in one machine can be done, as the example shows (IP 127.0.0.1 is local machine address).
It sounds like you should make the TCPclient calls from the DLL and let the other app be the server/TCPlistener waiting and accepting the calls.
 
Good point, I hadn't considered that... was gonna make the DLL the server, but it makes more sense the other way. I haven't converted the sample for tcp into my app yet to see if it will work... though there is significantly less code to worry about than named pipes, i'm sure it will work fine.
 
Back
Top