Google Answers Logo
View Question
 
Q: Named pipe problem ( No Answer,   8 Comments )
Question  
Subject: Named pipe problem
Category: Computers > Programming
Asked by: softwaredave-ga
List Price: $100.00
Posted: 17 Nov 2004 07:46 PST
Expires: 17 Dec 2004 07:46 PST
Question ID: 430173
I have implemented a multithreaded overlapped named pipe server on
Windows 2003 server, which opens up 26 instances of a named pipe. I
have 26 clients connecting to it, and the clients are permanently
connected. The clients are running Windows 2000 Pro SP4. The network
protocol is TCP/IP.

If I disconnect a client (for example by rebooting it or physically
disconnecting from the network), the server thread disconnects the
named pipe on the appropriate instance, then waits for a new
connection. When the client is restarted or reconnected The client can
reconnect to the pipe. This invariably works.

The server is issuing watchdog messages every 5 seconds to all connected clients.

However, unfortunately part of the network is experiencing problems.
This is being looked into. The clients on this section of the network
occasionally fail to receive the watchdog messages. I believe this is
due to the network problems, certainly the problem is not seen on
other clients.

After 5 minutes of no messages, the client closes the handle on its
end of the named pipe, then re-opens it after about 10 seconds, to try
to reconnect.

The server sees the client close the handle, so it calls
DisconnectNamedPipe, then ConnectNamedPipe. From logs, I can see that
the server does this without error and is waiting for a new
connection.

Usually this is successful. However, occasionally (say 1% of the time)
the client cannot reconnect, and GetLastError() returns 231, or
ERROR_PIPE_BUSY. The server is then sat there waiting for a client to
connect, but the client cannot connect because it says all pipe
instances are busy. The client keeps retrying, but fails.

The client can be pinged at this point, and browsed over the network,
but the named pipe seems to be permanently broken somehow.

At this point the only solution is to restart the server application -
restarting the client computer has no effect. Presumably I could also
fix it by disconnecting all pipe instances at the server, closing the
handle and recreating the named pipe, but as far as the server is
aware, there is no problem (yes, there is an unused connection but it
may be deliberate - the client may be offline for maintenance), so I
cannot detect this situation.

Brief server pseudo-code:

CreateNamedPipe()
start 26 threads, each thread:
loop:
   ConnectNamedPipe()
   Wait for (connect) event
   WriteFile/ReadFile until disconnection
   CancelIO
   DisconnectNamedPipe()
   goto loop

All return values are checked for errors.

My question is: why is the client reporting ERROR_PIPE_BUSY when the
server has called a ConnectNamedPipe()?
Answer  
There is no answer at this time.

Comments  
Subject: Re: Named pipe problem
From: shadowbq-ga on 17 Nov 2004 13:58 PST
 
Are You sure that the ConnectNamedPipe is being called after the
DisconnectNamedPipe when it detects the client is closed?

Create some logging to ensure that when you see these 1% errors that
it did infact close the old pipe and create a new one.

The best I can for now..
Subject: Re: Named pipe problem
From: softwaredave-ga on 17 Nov 2004 17:12 PST
 
Yes, as I show in the pseudo-code loop the DisconnectNamedPipe must
occur before the ConnectNamedPipe, and logging bears this out. The
reason it breaks out of the WriteFile/ReadFile section is usually a
"broken pipe" error when you pull the network cable or "pipe ended" if
you shut down the client (or errors to that effect, anyway), and there
is no apparent difference in the error when this problem occurs.
Unfortunately it's impossible to force this error, it happens only on
site, and it's one of those situations where you don't find out for
several hours.
Note that I don't "close" the pipe and create a new one, I simply
disconnect and reconnect an instance.
Also wouldn't ConnectNamedPipe fail if I hadn't called
DisconnectNamedPipe first? When I create the named pipe originally, I
tell it 26 instances, then immediately start threads which
ConnectNamedPipe on all of them. If one thread didn't do a
DisconnectNamedPipe, presumably the subsequent ConnectNamedPipe would
fail.

Dave

P.S. Incidentally this is written in C using MSVC 6 and the latest
service packs & SDK (I think March 2003).
Subject: Re: Named pipe problem
From: chinyue-ga on 21 Nov 2004 23:01 PST
 
You should call WaitNamedPipe() if your client's CreateFile() returns
ERROR_PIPE_BUSY.

Excerpt from MSDN:

// Try to open a named pipe; wait for it, if necessary.
while (1)
{ 
	hPipe = CreateFile(
		lpszPipename,   // pipe name
		GENERIC_READ |  // read and write access
		GENERIC_WRITE,
		0,              // no sharing
		NULL,           // default security attributes
		OPEN_EXISTING,  // opens existing pipe
		0,              // default attributes
		NULL);          // no template file

	// Break if the pipe handle is valid.
	if (hPipe != INVALID_HANDLE_VALUE)
		break;

	// Exit if an error other than ERROR_PIPE_BUSY occurs.
	if (GetLastError() != ERROR_PIPE_BUSY)
	{
		printf("Could not open pipe");
		return 0;
	}

	// All pipe instances are busy, so wait for 20 seconds.
	if (!WaitNamedPipe(lpszPipename, 20000))
	{
		printf("Could not open pipe");
		return 0;
	}
}
Subject: Re: Named pipe problem
From: softwaredave-ga on 22 Nov 2004 04:04 PST
 
Thanks for your comment. 

I don't call WaitNamedPipe, because I can't have the client end just
sitting there for 20 seconds, as it has other things to do. Yes, I
realise I could do it in a thread but I didn't see the point.
Instead, if the client fails to CreateFile (for any reason), it simply
tries again every 5 seconds, basically on a WM_TIMER message.

Are you saying that WaitNamedPipe is mandatory if CreateFile fails
with ERROR_PIPE_BUSY? If so, then you may have found the problem.
Subject: Re: Named pipe problem
From: chinyue-ga on 23 Nov 2004 19:56 PST
 
Yes. I think WaitNamedPipe() is a mandatory procedure to open server
named pipe. In fact, I always call WaitNamedPipe() (and wait forever
:) before CreateFile() on client side. This is the same way 'Win32
Systems Programming' 2nd page 309-310 says.
Subject: Re: Named pipe problem
From: softwaredave-ga on 24 Nov 2004 02:58 PST
 
Interesting. I did a quick Google using the terms WaitNamedPipe
mandatory and found this:
http://www.developer2.com/features/stories/33490.html.
Although the terms do not appear together, the example client code
here also calls WaitNamedPipe before CreateFile.
I don't have 'Win32 Systems Programming', I mainly use MSDN or the SDK docs. 
Perhaps WaitNamedPipe does do something "magic" that CreateFile on its
own doesn't do. If this is the case, then it looks like (yet another
!) case of Microsofts documentation being inadequate. AFAIK nowhere
does it say that WaitNamedPipe is necessary, it's there in the
samples, yes, but then so is printf and that's not going to do much ;)
WaitNamedPipe just looks like a high-efficiency way of waiting for an
instance to become free.
Really all I can do is mod the code to put in a WaitNamedPipe before
the CreateFile on the client side. I'm assuming I don't have to use 20
seconds, I can use, say, 500 milliseconds, although now I'm beginning
to wonder if 20 seconds is also mandatory....
As I mentioned before unfortunately this problem is random. Sometimes
we have weeks between occurrences. What I will do is update the code
on, say, half the clients and then see what happens. What I do know is
that there are certain clients that exhibit the problem more than
others.
So thanks, I don't yet know if this counts as THE answer, so I don't
know what happens now - it's my first Google question!
Dave
Subject: Re: Named pipe problem
From: softwaredave-ga on 24 Nov 2004 03:09 PST
 
Having reflected on the above for all of 10 minutes :), I have my
doubts that this is the answer.
When the condition occurs, rebooting the clients has no effect. The
only way of clearing it is to close down the pipe at the server and
restart it. So unless calling WaitNamedPipe at a client somehow
affects the server, this cannot resolve the problem. :(
Subject: Re: Named pipe problem
From: reinhard123-ga on 29 Oct 2005 14:09 PDT
 
could reproduce and solve this problem. outline:

fOk = WaitNamedPipe(sz, NMPWAIT_USE_DEFAULT_WAIT); //or try other wait values!

if (fOk)  {
   hpipe = CreateFile(sz, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

// for some reasons pipe MIGHT BE NOT ready yet (do not trust fOK) 
   while (hpipe == INVALID_HANDLE_VALUE)
      hpipe = CreateFile(sz, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
...

It seems that this question has timed out, nevertheless i am courious
what the reason for this behaviour could be. a problem with completion
ports ? or or simply a mistake we made ? some smart people out there ?

additional info
client: xpprof, sp2, msvc6, mfc; server w2k, sp4, msvc6, plain c (ntservice)

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy