Creating Unidirectional Message-based Named Pipe

F

FB's .NET Dev PC

I am writing two services in VB.NET, one of which needs to send text strings
to the other. After reading, I
decided (perhaps incorrectly) that named pipes would be the best
interprocess communication method
for this task.

I set about creating, on the pipe's server side, a new thread which would
instantiate a blocking inbound message pipe, and the
client side which would write to that pipe when needed. Being on the same
PC, security is not an issue (I think).

I first tried MS example from the KB article
(http://support.microsoft.com/?kbid=871044) plugged into my
services at the appropriate locations (threads and all) and it works as
advertised. The only problem there
is that this is a bidirectional pipe that transports an integer and a byte
array.

I have spent a few days trying to change the code. The latest simple attempt
is to change the pipe type to INBOUND.
When I do so, I get an error 5 (Invalid procedure call) on the client side.
(short PIPE_ACCESS_INBOUND=&H1s)

I have tried changing the declaration of the sample to a string or 1
dimensional Byte array (rather than an Integer) and get an
error 1214 (type mismatch) in the Error object's LastDLLError. According to
my Win32 API book (Appleman) this declaration is type ANY,
so I should be able to change the type, as long as they match on both ends
of the pipe, right?

SERVER SIDE DECLARATION (from the KB article):
Declare Function CreateNamedPipe Lib "kernel32" Alias "CreateNamedPipeA" _
(ByVal lpName As String, ByVal dwOpenMode As Integer, _
ByVal dwPipeMode As Integer, ByVal nMaxInstances As Integer, _
ByVal nOutBufferSize As Integer, ByVal nInBufferSize As Integer, _
ByVal nDefaultTimeOut As Integer, ByVal lpSecurityAttributes As IntPtr _
) As Integer

Declare Function ConnectNamedPipe Lib "kernel32" _
(ByVal hNamedPipe As Integer, ByVal lpOverlapped As Integer) As Integer

Declare Function ReadFile Lib "kernel32" _
(ByVal hFile As Integer, ByRef lpBuffer As INTEGER,
_<<<<---------------------change here
ByVal nNumberOfBytesToRead As Integer, ByRef lpNumberOfBytesRead As Integer,
_
ByVal lpOverlapped As Integer _
) As Integer


CLIENT SIDE MATCHING DECLARATION:
Public Declare Function CallNamedPipe Lib "kernel32" Alias "CallNamedPipeA"
_
(ByVal lpNamedPipeName As String, _
ByRef lpInBuffer As INTEGER,
_<<<<--------------------------------------------change here
ByVal nInBufferSize As Integer, _
ByRef lpOutBuffer As Byte, _
ByVal nOutBufferSize As Integer, _
ByRef lpBytesRead As Integer, ByVal nTimeOut As Integer) As Integer


1) Does anyone have example code for such a pipe? (client to server
communication, message-type, text messages)
2) Does anyone have any idea why changing the declared type from integer to
anything else causes such problems?
3) Is there a good way to debug these problems with API calls?


Sorry if I'm missing something obvious, I've only started switching to .NET
for 3 weeks now...Please be gentle!
Thanks!
FB
 
F

FB's .NET Dev PC

Hi, Cor

I appreciate the suggestion. I am sorry to say that it did not provide the
information I needed to accomplish my goal. I have checked a lot of
different leads (anything I could find as an online reference) and it seems
that no one is doing this in VB.

Let me ask this, then.

In the server application, I have created a separate thread for this named
pipe server (see code below). I then create my pipe as a blocking pipe
(PIPE_WAIT) in this separate thread.

In the development environment, as I run this code, the main application
thread blocks as well as the child thread upon the pipe wait condition. The
question is this: this condition only occurs in the development environment,
right? Once compiled, a pipe block only affects the immediate thread?

Public Class SmCSLogPipeClass

Public Sub PipeToOPCcommSvc()

'create a pipe and read from it

Dim hPipe As Integer

Const pipeName As String = "\\.\pipe\SMC_NP_OCS_SLS"

Dim openMode, pipeMode As Integer

Dim byteIn, res, cbnCount As Integer

'Create the named pipe

openMode = PIPE_ACCESS_DUPLEX Or FILE_FLAG_WRITE_THROUGH

pipeMode = PIPE_WAIT Or PIPE_TYPE_MESSAGE Or PIPE_READMODE_MESSAGE

hPipe = CreateNamedPipe(pipeName, openMode, pipeMode, 10, 10000, 2000,
10000, IntPtr.Zero)

[etc]

end class



....some module code here...

Dim LogPipe As New SmCSLogPipeClass

Dim oCommThread As System.Threading.Thread

oCommThread = New Thread(New ThreadStart(AddressOf
LogPipe.PipeToOPCcommSvc))

oCommThread.Start()


Thanks much,
Fred Bourdelier, DBA
Krebs Engineers
Tucson AZ USA
 

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

Top