您可以使用单个命名管道客户端进行读写吗?

Posted

技术标签:

【中文标题】您可以使用单个命名管道客户端进行读写吗?【英文标题】:Can you read and write with a single Named Pipe client? 【发布时间】:2011-12-08 17:11:55 【问题描述】:

我编写了一个小应用程序,它创建了一个命名管道服务器和一个连接到它的客户端。可以向服务器发送数据,服务器读取成功。

接下来我需要做的是从服务器接收消息,所以我有另一个线程来生成并等待传入​​数据。

问题在于,当线程等待传入数据时,您无法再向服务器发送消息,因为它挂在 WriteLine 调用上,因为我假设管道现在正在检查数据。

难道只是我没有正确处理这个问题吗?还是命名管道不应该像这样使用?我在命名管道上看到的示例似乎只有一种方式,客户端发送和服务器接收,尽管您可以将管道的方向指定为 InOut 或两者。

任何帮助、指点或建议将不胜感激!

这是到目前为止的代码:

// Variable declarations
NamedPipeClientStream pipeClient;
StreamWriter swClient;
Thread messageReadThread;
bool listeningStopRequested = false;

// Client connect
public void Connect(string pipeName, string serverName = ".")

    if (pipeClient == null)
    
        pipeClient = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut);
        pipeClient.Connect();
        swClient = new StreamWriter(pipeClient);
        swClient.AutoFlush = true;
    

    StartServerThread();


// Client send message
public void SendMessage(string msg)

    if (swClient != null && pipeClient != null && pipeClient.IsConnected)
    
        swClient.WriteLine(msg);
        BeginListening();
    



// Client wait for incoming data
public void StartServerThread()

    listeningStopRequested = false;
    messageReadThread = new Thread(new ThreadStart(BeginListening));
    messageReadThread.IsBackground = true;
    messageReadThread.Start();


public void BeginListening()

    string currentAction = "waiting for incoming messages";

    try
    
        using (StreamReader sr = new StreamReader(pipeClient))
        
            while (!listeningStopRequested && pipeClient.IsConnected)
            
                string line;
                while ((line = sr.ReadLine()) != null)
                
                    RaiseNewMessageEvent(line);
                    LogInfo("Message received: 0", line);
                
            
        

        LogInfo("Client disconnected");

        RaiseDisconnectedEvent("Manual disconnection");
    
    // Catch the IOException that is raised if the pipe is
    // broken or disconnected.
    catch (IOException e)
    
        string error = "Connection terminated unexpectedly: " + e.Message;
        LogError(currentAction, error);
        RaiseDisconnectedEvent(error);
    

【问题讨论】:

当然,只要您不需要异步,这是可能的。那是真正的独立性,而您使用 2 个管道进行读写意味着真正的独立性,我想这样命名它们。 听起来有点神秘。所以我认为您是说应该有一个用于读取的管道和另一个用于写入的管道,因为您在任何时候都只能使用一个操作?如果是这样,那是有道理的 【参考方案1】:

您不能从一个线程读取并在另一个线程上写入同一个管道对象。因此,虽然您可以创建一个协议,其中侦听位置根据您发送的数据而变化,但您不能同时进行这两项操作。您将需要双方都有一个客户端和服务器管道来执行此操作。

【讨论】:

以上是关于您可以使用单个命名管道客户端进行读写吗?的主要内容,如果未能解决你的问题,请参考以下文章

您可以通过命名管道自托管 ServiceStack 吗?

通过重叠 IO 的异步命名 Windows 管道通信

C/S模型之命名管道

我们可以用 boost.asio 创建未命名的套接字来模拟匿名管道吗?

进程间通信--FIFO(命名管道)

我需要刷新命名管道吗?