| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| subject: | named pipes |
CM> Ahhh. That's what I was thinking too. WOuld you give
CM> each client process a differnet pipe? Or have one
CM> pipe global to all instances, and have all clients
CM> Open and write to it?
This has been some cause of confusion. There exists nothing I would call a
"global pipe". There is what they call a "many
instance" pipe,but the only thing each instance has in common is the
name. In other words, even though each client uses the exact same name to
open the pipe in the server process, each of these pipes is distinct.
It usually works something like this:
1) The first time the server process calls DosCreateNPipe() it
defines how many times the pipe name can be reused. The server
process starts up a thread for each pipe instance it plans to
support. Each thread does a DosCreateNPipe(), followed by a
DosConnectNPipe(). The DosConnectNPipe() will block until a
client connects (I assume you're using a blocking pipe, because
using anything else in an OS/2 program is silly).
The server always creates the pipe with a name like "\pipe\name".
You can have a "path", like
"\pipe\foo\foo\name", but in the
past I found that this will break some network redirectors.
In the eyes of the server, the pipe is always considered a
"local pipe", even if a remote client is using it (therefore, you
CAN use DosSetNPipeSem() on it, although I have never found
"pipe sems" to be very useful).
2) The client uses the pipe using standard open/read/write/close
calls. You can even use C runtime calls to do this with many
compilers. You may have to call DosSetNPHState() to change the
mode of the pipe, however. A DOS program may not want to use a
blocking-mode pipe for example. The default read mode for the
pipe is "Message mode" (as opposed to "byte
mode"). I recomend
using message mode, it makes coding your hll easier.
If DosOpen() returns ERROR_PIPE_BUSY, it means that all of the
instances of the pipe are in use. The program must abort, or
wait for an intance to become free (DosWaitNPipe()).
The client can form the name of the pipe two ways:
"\pipe\foo" -- local pipe
"\\computername\pipe\foo" -- remote pipe.
In both of these cases, the server process would have created
the pipe as "\pipe\foo", since the
"computername" part of it is
handled by the NOS.
ps: When using a C compiler, it is just fine to name a pipe
"/pipe/foo". Otherwise, you might end up with something ghastly
like this: "\\\\server\\pipe\\foo". I'm not too sure about
"//computername", however, for all networks; Works great with LS
3.
Once the client is connnected, it has a completely private
conversation with the process or thread that called
DosConnectNPipe() at the other end. Most of the confusion with
multiple instance pipes was many people thought there was one end
at the server, with many client ends (in other words, the
server was more like a broadcast TV station). This is not the
case. Look towards LM/LS MailSlots of you need to broadcast a
message.
3) Once each side is connected, the pipe is pretty much equal.
Both sides simply call DosWrite/DosRead to send messages. When
the pipe is in message-mode, things are quite easy, since you
never have to worry about only getting part of a message with
each DosRead; you either get the entire message that the other
side DosWrote, or an error telling you that your buffer was too
small to hold it.
Each DosRead(), no matter how big your buffer is, will only
return one message at a time. This makes it very easy to write
your application code. If someone out there is using a byte-mode
pipe, I'd like to know why; I've never found a use for one.
4) When the client is done with the pipe, it calls DosClose() (or
fclose() or whatever).
When the server is done, it calls DosDisConnectNPipe() then loops
back to DosConnectNPipe(), to get ready for the next client that
comes along (unless using the alternate method described next; in
which case it closes the pipe when it is done with it, and the
service thread terminates).
An alternate way to implement the server is to have only one thread that
calls DosCreateNPipe/DosConnectNPipe to start off each conversation,then
spawn a thread to service it. The "connect thread" then quickly
loops back and gets ready to connect another thread. I like this better
because you only have as many threads as you need running. The drawback is
that there is a small window of time when there is no
"connectable" pipe, so the client program must not get upset if
it receives an error when opening the pipe (it should retry for a few
seconds).
Why bother using a multiple instance pipe, if each pipe is distinct?
Because you can hard-wire the pipe name in the client programs. Otherwise,
you would have to configure each client to use a different name. Other
remote IPC's (ipx/netbios/etc) can't do this; they would have to set up a
hard-wired "name service" on the server that would assign them a
private name to use. The "name service" is a contention point.
--- Maximus/2 2.01
* Origin: Beer bellies = great waist. (905)858-8488 (1:259/414)SEEN-BY: 12/2442 54/54 620/243 624/50 632/348 640/820 690/660 711/409 413 430 SEEN-BY: 711/807 808 809 934 942 712/353 623 713/888 800/1 @PATH: 259/414 400 99 98 3615/50 229/2 12/2442 711/409 54/54 711/808 809 934 |
|
| SOURCE: echomail via fidonet.ozzmosis.com | |
Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.