Paul Farry
Paul Farry

Reputation: 4768

Correct way to Reuse a NamedPipeServerStream in Byte Mode and Asynchronous

I'm setting up a named pipe server and I reading from the Server Pipes... I have 5 possible concurrent connections allowed and they are setup like this.

Public Sub Start()
    Dim i As Integer
    While i < mTotalServers
        Dim s As New IO.Pipes.NamedPipeServerStream("IPSClient", IO.Pipes.PipeDirection.InOut,
                 mTotalServers, IO.Pipes.PipeTransmissionMode.Byte, IO.Pipes.PipeOptions.Asynchronous)
        i += 1
        Dim p As New PipeConnection(s, "Index - " & i)
        mServers.Add(p)

        s.BeginWaitForConnection(New AsyncCallback(AddressOf ConnectionReceived), p)
    End While
End Sub

I then resume operation until a connection is received.

Private Sub ConnectionReceived(ar As IAsyncResult)
    Try
        Dim p As PipeConnection = Nothing
        If ar.IsCompleted Then
            Diagnostics.Debug.Print("Connection received")
            p = CType(ar.AsyncState, PipeConnection)
            Dim s As IO.Pipes.NamedPipeServerStream = p.Stream
            s.EndWaitForConnection(ar)

            Dim conn As Connection = New Connection(p)

            While mRunning AndAlso p.Stream.IsConnected
                If p.ReadHandle.WaitOne(100) Then
                    Debug.Print("Set")
                Else
                    '
                End If
            End While

            If mRunning Then
                s.BeginWaitForConnection(New AsyncCallback(AddressOf ConnectionReceived), p)
            End If
        Else
            p.Stream.Close()
            p.Stream.Dispose()
        End If

    Catch ex As ObjectDisposedException
        ' Diagnostics.Debug.Print(ex.ToString)
    Catch ex As OperationCanceledException
        Diagnostics.Debug.Print(ex.ToString)
    Catch ex As IO.IOException
        Diagnostics.Debug.Print(ex.ToString)
    End Try
End Sub

Once the Client end of the Pipe disconnects, I want the Pipe to be available for reuse.

The Part where I am Looping While mRunning and connected, is this how I should be doing it, or is there a better way? (my reading Code all occurs inside the Connection Class)

Also at the bottom of the block where I BeginWaitForConnection again, is that correct?

Upvotes: 3

Views: 3713

Answers (1)

Chris Dickson
Chris Dickson

Reputation: 12135

...at the bottom of the block where I BeginWaitForConnection again, is that correct...

No, it isn't. Once connected, an instance of NamedPipeServerStream is simply a Stream wrapped around a pipe instance connecting the server to a particular client. It isn't designed to be reused. Your code should just hand this instance over to your Connection object, which should ensure that it is disposed when the communication with that client is finished.

To reuse the "slot" in mServers which is freed up when a client connection is finished with, you need somewhere to instantiate a new NamedPipeServerStream and call BeginWaitForConnection on that. It looks as though your PipeConnection class might be the place to implement that.

Upvotes: 2

Related Questions