WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Tutorials
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Named Pipes

 Keywords: Named Pipes Interprogram Messages Communication Protocol 

Named Pipes

Named pipes is an interprogram communication protocol for sharing information between two applications either running on the same system, or on different computers in a network.

It hides all the communication details and offers two sides: A 'Client' side to request data be sent or recieved and a 'Server' side to act upon the clients request. For opening up a communication line, a process creates a pipe with a unique name. Using this name another process can connect to this pipe. Because a named pipe is a link between only two processes, it needs additional sets of named pipes to communicate with more then two processes at the same time. Each instance of these named pipes can use the same name.

The reading or writing of data to a pipe can be done with the the following set of WIL commands:


PipeClientOpen(pipe-name, timeout)
Connects to a named pipe.

PipeClientSendRecvData(pipe-handle, data, read-timeout)
Writes a message to a named pipe and then reads a message back.

PipeClientClose(pipe-handle)
Closes a named pipe connection.


PipeServerCreate(pipe-name, timeout)
Creates an instance of a named pipe and waits for a client to connect. (Windows NT family only)

PipeServerRead(pipe-handle:, timeout)
Reads a message from a named pipe.

PipeServerWrite(pipe-handle, data)
Writes a message to a named pipe.

PipeServerClose(pipe-handle, timeout)
Closes a named pipe instance.


PipeInfo(request, pipe-handle)
Returns information about a pipe or pipe operation.


You will notice there are both client and server functions. Each is designed specifically for its task. If we're going to have interprogram communication, we have to design our script so that the communication takes place properly, that all the data is transmitted, and that there are matching open and close operations. So, we have functions to create pipes, connect to them and to disconnect from them. The create routine creates the pipe, the connect waits for the client to connect to the pipe that we've just created. When the entire process has finished, we disconnect from the pipe, and we can either end our application, or continue with the cycle.

Here are two sample scripts: a server script creates a "named pipe" and waits for a client to connect. It reads a message from the client and sends back a reply. The client script sends a message and displays the reply from the server.

The server script example (below) creates a named pipe called 'fluggle' using the PipeServerCreate function. It then waits for a client script to connect to it using the same named pipe 'fluggle'. Once a client script connects the server reads a message from a named pipe using PipeServerRead. It then checks that the data was valid. This server script was only designed to deal with a 'GET_TIME' request. If the client sends that specific request then the server script gets the current time using the TimeYmdhms function. Now the server script need to send its reponse (current server time) back to the client. This is accomplished using the PipeServerWrite function. And finally the server script closes a named pipe instance using PipeServerClose. Then it starts all over again, waiting for a client script to connect with that named pipe.

SERVER.WBT
The 'server'

	pipename="\\.\pipe\fluggle"
	   timeout = -1
	   IntControl(12,5,0,0,0);terminate quietly
	   notice = StrCat(@CRLF,@CRLF,"[ Press CTRL+BREAK to exit script ]")
	   BoxOpen("Time Server","Initializing - Awaiting connect from Client")
	   While @TRUE ; General  Server loop
	      pipehandle = PipeServerCreate(pipename,timeout)
	      If pipehandle=="*ERROR*" || pipehandle=="*TIMER*" Then Continue
	      readinfo = PipeServerRead(pipehandle, timeout)
	      If readinfo=="*ERROR*" || readinfo=="*TIMER*"
	         PipeServerClose(pipehandle,0)
	         Continue         ; try again
	      EndIf
	      If readinfo == "GET_TIME"
	         response= TimeYmdHms()
	      Else
	         response = "ERROR: UNKNOWN REQUEST"
	      EndIf
	      rslt=PipeServerWrite(pipehandle,response)
	      BoxText(StrCat("Data sent to client = ",response, notice))
	      PipeServerClose(pipehandle,timeout)
	   EndWhile
	   Exit
	


The client script example (below) connects to a pre-existing server created named pipe called 'fluggle' using the PipeClientOpen function. It then waits for the server script to return a pipe handle. Once a client script gets a valid pipe handle it writes a message (GET_TIME) to the named pipe and then reads a message back using PipeClientSendRecvData.

PipeClientSendRecvData returns a message string on success which in this case should be the servers time in the format YYYY:MM:DD:HH:MM:SS. And finally the client script closes the named pipe connection using PipeClientClose. Then it starts all over again.

Note: In the example programs, the pipe name is coded as "\\.\pipe\fluggle", where "\\.\" means "on this computer". To communicate with a server on another system, code the name in the client, as "\\HostComputer\pipe\fluggle".

CLIENT.WBT
The 'client'

   SERVER = "." ;for the local machine or "myserver" for remote machine
   pipename = "fluggle"
   pipepath = StrCat("\\",SERVER,"\pipe\",pipename)
   querydata = "GET_TIME"
   timeout = -1
   IntControl(12,5,0,0,0);terminate quietly
   notice = StrCat(@CRLF,@CRLF,"[ Press CTRL+BREAK to exit script ]")

   BoxOpen("Time Client","Initializing connection to server...")
   While @TRUE
      pipehandle = PipeClientOpen(pipepath,timeout)
      If pipehandle=="*ERROR*" || pipehandle=="*TIMER*" Then Continue ; try again
      data=PipeClientSendRecvData(pipehandle, querydata,timeout)
      BoxText(StrCat("Data sent from server = ", data, notice))
      PipeClientClose(pipehandle)
   EndWhile
   Exit
   

See the Windows Interface Language help file for documentation on the various Named Pipe functions.


Requirements for network connections

Before an access check can be performed on the named pipe to determine if you have access to it, you have to pass the authentication check itself. On computers that are domain members, when logged on as a domain account, the authentication check is usually transparent unless certain systems have been modified to deny logon rights such as network mode access.

When you are dealing with computers that are not domain members, then the authentication check is not transparent and will fail unless you have already performed some sort of network access to the remote system that established your identity for the connection with a set of credentials that are valid on the remote system [e.g. a local account on that system]. Typically, this is done by establishing a network connection to the "IPC$" share on the remote system. In WB, you can do with with a call to wntAddDrive() where you specify the "IPC$" share, a set of credentials and no drive letter. Once a connection to this share is established, all following attempts to connect to SMB folder shares or to named pipes will transparently pass through the authentication check.


Article ID:   W17354
File Created: 2011:12:30:13:18:22
Last Updated: 2011:12:30:13:18:22