命名管道在写入时挂起

7

我正在制作一个多客户端命名管道服务器。客户端已经成功连接到服务器,但是每当我尝试通过服务器或客户端写入管道时,代码都会在write方法上挂起。有什么原因导致写入方法被卡住吗?

服务器代码:

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);
        }
    }
}

这是我的客户端代码:

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);     
}

你尝试将“PipeTransmissionMode”设置为“Byte”了吗? - SuperOli
是的,我尝试过了,可惜什么也没改变。 - tareqx3
我也尝试过从服务器和客户端中删除读取线程,仅尝试向管道写入数据,但仍然卡住了。 - tareqx3
2个回答

7

我仍然不确定写入者在等待什么,但我找到了一个解决方案/解决方法来解决我的问题。通过将NamedPipe构造函数中的PipeOptions设置为异步,读取/写入操作完成成功!


0

我也遇到了以下情况的问题:

  1. 服务器向管道写入数据
  2. 在第一步完成后,客户端读取管道,并立即向管道写入响应
  3. 服务器尝试再次向管道写入数据,而不是读取客户端先前写入的内容。

我通过在每个write调用之前读取管道来解决这个问题,这对我很有帮助。

我不完全确定,但我认为这可能是为了防止数据丢失,管道会像“忙碌”一样等待被读取。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接