ncite
ncite

Reputation: 563

Windows named pipe doesn't respond correctly for concurrent requests

I used named pipe for internal communication inside of one program (on Windows XP). The named pipe works fine for multiple connections when I connected 2-3 clients. However it seems to be jammed when I apply several connections concurrently (for example 10), only a few of connections could be accepted by ConnectNamedPipe() and The communication seems to be jammed.

But when I debugged in client code, I found out that all client CreateFile functions returned correctly with file handles (seems to be correct ones). It is confusing since I watched the CreateNamedPipe loop and it only creates about half of the handles...

Server Part:

       while (!isPipeServerClosed)
        {
            try
            {
                filehandle = CreateNamedPipe(
                this.pipeName,
                DUPLEX | FILE_FLAG_OVERLAPPED,
                PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
                255,
                InBufferSize,
                InBufferSize,
                0,
                IntPtr.Zero);
                if (ConnectNamedPipe(filehandle, IntPtr.Zero) > 0)
                {

                    PipeThread pipe = new PipeThread(filehandle);
                    sPipeThreadList.Add(pipe);
                }
            }
            catch (Exception exp)
            {
                System.Console.WriteLine(exp.StackTrace);
            }

        }

Client Part, simple Delphi code (behaves the same even when I tried with WaitNamedPipe ):

  FHandle := INVALID_HANDLE_VALUE;
  FHandle := CreateFile(PChar(FPipeName),GENERIC_READ or GENERIC_WRITE,
        0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
  // create the class
  if FHandle = INVALID_HANDLE_VALUE then
  begin
    Connected := false;
  end

Could I know what did I miss? Thank you!

Upvotes: 2

Views: 937

Answers (1)

Chris Dickson
Chris Dickson

Reputation: 12135

You are not using overlapped operation correctly. In particular:

If hNamedPipe was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hNamedPipe was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the connect operation is complete.

also, I imagine that sometimes your ConnectNamedPipe calls will be returning with errors because the client has not yet connected (ERROR_IO_PENDING). In these cases your clients will be 'orphaned' when their connections complete, because you won't have created a PipeThread for them.

If you want to use overlapped mode, you should do some more study and implement it properly. Alternatively, if you remove the FILE_FLAG_OVERLAPPED from the arguments to CreateNamedPipe, then ConnectNamedPipe will block until a client has connected and this problem will not occur, though you will have a different problem: how to unblock when you want to stop the server (you'll find some answers to that here on SO, IIRC).

Upvotes: 1

Related Questions