tareqx3
tareqx3

Reputation: 591

Named Pipe hangs on write

I'm making a multi-client Named Pipe server. The clients are connecting to the server correctly, but whenever I attempt to write to the pipe through the server or the client, the code hangs on the write method. Any reason as to why the write methods are getting stuck?

Server code:

public void ListenForConnections()
{
    Thread startListening = new Thread(AcceptConnections);
    startListening.Start(PipeName);
}

public static void AcceptConnections(object ServerPipeName)
{
    while (true)
    {
        try
        {
            NamedPipeServerStream pipeServer = 
                 new NamedPipeServerStream(ServerPipeName.ToString(),
                                           PipeDirection.InOut, 
                                           NamedPipeServerStream.MaxAllowedServerInstances,
                                           PipeTransmissionMode.Message);

            pipeServer.WaitForConnection();
            pipeServer.ReadMode = PipeTransmissionMode.Message;
            //A client has connected
            Pipes.Add(pipeServer);
            index++;

            Thread Poll = new Thread(PollPipe);
            Poll.Start(pipeServer);
            }
            catch (Exception ex)
            {
                return;
            }
        }
    }

    public static void PollPipe(Object Pipe)
    {
        byte[] bytes = new byte[1024];
        NamedPipeServerStream PipeStream = (NamedPipeServerStream)Pipe;
        MemoryStream ms = new MemoryStream();
        do 
        {
            ms.Write(bytes, 0, PipeStream.Read(bytes, 0, bytes.Length));
        } while (!PipeStream.IsMessageComplete);   
    }

    public void BroadcastObject(GlassSquidObject obj)
    {
        long length = 0;
        byte[] bytes;

        SoapFormatter formatter = new SoapFormatter();

        using (MemoryStream ws = new MemoryStream())
        {
            formatter.Serialize(ws, obj);
            length = ws.Length;
            bytes = ws.GetBuffer();
        }

        for (int i = 0; i < Pipes.Count; i++)
        {
            Pipes[i].Write(bytes, 0, bytes.Length);
        }
    }
}

This is the code for my client:

public bool ConnectToPipe()
{
    if (String.IsNullOrWhiteSpace(PipeName))
        return false;

    PipeClient = new NamedPipeClientStream(Address, PipeName, PipeDirection.InOut);

    try
    {
        PipeClient.Connect(5000);

        Thread readThread = new Thread(PollPipe);
        readThread.Start(PipeClient);
    }
    catch (Exception ex)
    {
        return false;
    }

    return true;
}

public bool WriteObject(GlassSquidObject obj)
{
    long length = 0;
    byte[] bytes;

    try
    {
        SoapFormatter formatter = new SoapFormatter();

        using (MemoryStream ws = new MemoryStream())
        {
            formatter.Serialize(ws, obj);
            length = ws.Length;
            bytes = ws.GetBuffer();
        }

        PipeClient.Write(bytes, 0, bytes.Length);
    }
    catch (Exception ex)
    {
        return false;
    }

    return true;
}

public static void PollPipe(Object Pipe)
{
    byte[] bytes = new byte[1024];
    NamedPipeClientStream PipeStream = (NamedPipeClientStream)Pipe;
    PipeStream.ReadMode = PipeTransmissionMode.Message;
    MemoryStream ms = new MemoryStream();
    do
    {
        ms.Write(bytes, 0, PipeStream.Read(bytes, 0, bytes.Length));
    } while (!PipeStream.IsMessageComplete);     
}

Upvotes: 7

Views: 5460

Answers (2)

Arthur Groll
Arthur Groll

Reputation: 5

I was also facing this problem with the following situation:

  1. The server writes to the pipe
  2. After step 1, the client reads the pipe, and right afterwards writes a response to the pipe
  3. The server tries to write again to the pipe without reading what was previously written by the client.

I solved it by reading the pipe before each write call, and it solved the problem for me.

I'm not entirely sure, but I think this may be caused to prevent data loss, and the pipe acts like it is "busy", waiting to be read.

Upvotes: 0

tareqx3
tareqx3

Reputation: 591

I'm still not sure what the write was waiting for, but I found a solution/workaround to my problem. By setting the PipeOptions in the NamedPipe constructors to Asynchronous, the read/writes completed succesfully!

Upvotes: 7

Related Questions