Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 命名管道流示例未显示结果_C#_Namedpipeserverstream - Fatal编程技术网

C# 命名管道流示例未显示结果

C# 命名管道流示例未显示结果,c#,namedpipeserverstream,C#,Namedpipeserverstream,我是新来的管道流,并试图实践。我已经编写了以下两个项目,但是我看不到客户机项目的结果(我在服务器项目中编写)。这是第一个项目: using (NamedPipeServerStream namedPipeServer = new NamedPipeServerStream("test-pipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message)) { byte[] bytes = Encoding.Default.GetByte

我是新来的管道流,并试图实践。我已经编写了以下两个项目,但是我看不到客户机项目的结果(我在服务器项目中编写)。这是第一个项目:

using (NamedPipeServerStream namedPipeServer = new NamedPipeServerStream("test-pipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message))
{
    byte[] bytes = Encoding.Default.GetBytes("Hello, it's me!\n");
    namedPipeServer.WaitForConnection();
    Console.WriteLine("A client has connected!");
    namedPipeServer.Write(bytes, 0, bytes.Length);
}
这是第二个项目:

using (NamedPipeClientStream namedPipeClient = new NamedPipeClientStream(".", "test-pipe", PipeDirection.InOut))
{
    namedPipeClient.Connect();
    namedPipeClient.ReadMode = PipeTransmissionMode.Message;
    string serverResponse = string.Empty;
    byte[] readBytes = new byte[5];
    while (!namedPipeClient.IsMessageComplete)
    {
        namedPipeClient.Read(readBytes, 0, readBytes.Length);
        serverResponse = Encoding.Default.GetString(readBytes);
        readBytes = new byte[5];
    }
    System.Console.WriteLine(serverResponse);
    byte[] writeBytes = Encoding.Default.GetBytes("Hello from client!\n");
    namedPipeClient.Write(writeBytes, 0, writeBytes.Length);
}
这个怎么了


感谢尝试使用
StreamReader
从两个管道读取消息。 服务器:

客户:

using (NamedPipeClientStream namedPipeClient = new NamedPipeClientStream(".", "test-pipe", PipeDirection.InOut))
{
    namedPipeClient.Connect();

    var reader = new StreamReader(namedPipeClient);
    var msg = reader.ReadLine();
    Console.WriteLine(msg);

    byte[] writeBytes = Encoding.Default.GetBytes("Hello from client!\n");
    namedPipeClient.Write(writeBytes, 0, writeBytes.Length);
    namedPipeClient.WaitForPipeDrain();
}

客户端没有收到来自服务器的任何消息,因为在执行读取操作后必须调用
namedPipeClient.IsMessageComplete
。请参见文档中的:

获取一个值,该值指示消息中是否有更多数据 从最近的读取操作返回

否则,
namedPipeClient.IsMessageComplete
返回
true
中的代码,而
-循环不执行。因此,您必须将
while
循环重写为
do-while
循环,以确保在测试
namedPipeClient.IsMessageComplete
之前执行读取操作

但还有更多问题,请参见注释以了解解释:

using (NamedPipeClientStream namedPipeClient = new NamedPipeClientStream(".", "test-pipe", PipeDirection.InOut))
{
    namedPipeClient.Connect();
    namedPipeClient.ReadMode = PipeTransmissionMode.Message;

    // StringBuilder is more efficient for string concatenation
    StringBuilder serverResponse = new StringBuilder();

    byte[] readBytes = new byte[5];

    do
    {
        // You need to store number of bytes read from pipe (to readCount variable).
        // It can be less then the length of readBytes buffer, in which case
        // GetString() would decode characters beyond end of message.
        var readCount = namedPipeClient.Read(readBytes, 0, readBytes.Length);
        var readText = Encoding.Default.GetString(readBytes, 0, readCount);

        // You original code "overwrites" content of serverResponse variable instead
        // of concatenating it to the previous value. So you would receive only 
        // the last part of the server message.
        serverResponse.Append(readText);

        // It is not needed to create new buffer, you can just reuse existing buffer
        //readBytes = new byte[5];

    // IsMessageComplete is now tested after read operation
    } while (!namedPipeClient.IsMessageComplete);

    System.Console.WriteLine(serverResponse.ToString());

    // You current server implementation exits as soon as it sends message to the client
    // and does not wait for incomming message. You'll have to change server accordingly 
    // to be able to send a message back to the server.
    //byte[] writeBytes = Encoding.Default.GetBytes("Hello from client!\n");
    //namedPipeClient.Write(writeBytes, 0, writeBytes.Length);
}

编辑: 当命名管道处于
PipeTransmissionMode.Message
模式时,服务器上对
NamedPipeServerStream.Write()
的每次调用都会将数据作为单独的消息通过管道发送。然后,客户端可以接收彼此分离的这些消息 (与
PipeTransmissionMode.Byte
模式相反,在该模式下,无论服务器使用
NamedPipeServerStream.Write()执行多少次写入操作,客户端都只接收单个连续的字节流)

当客户端从管道读取数据时(
namedPipeClient.Read()
),允许方法返回较少的请求数据(例如,当接收缓冲区中没有足够的空间来存储整个消息,或者消息比请求的字节数短时),请参阅

返回读入缓冲区的字节总数这个 可能小于请求的字节数,如果 字节当前不可用,如果流的结尾不可用,则为0 达到

然后,您可以使用
namedPipeClient.IsMessageComplete
readCount
来检测此问题。让我用一些例子来解释它:假设服务器向客户机发送消息
ABCDEFGHIJKL
,编码为字节数组
{65、66、67、68、69、70、71、72、73、74、75、76}
。此消息的长度为12字节,因此它不适合5字节长的接收缓冲区(
readBytes
)。因此,当客户端首次使用
namedPipeClient.Read()
从管道中读取时,接收缓冲区将只包含消息的前5个字节(
{65、66、67、68、69}
,对应于
ABCDE
)。这就是
namedPipeClient.IsMessageComplete
将帮助我们的地方,因为它将返回
false
,表明我们没有收到完整的消息,还有一些字节,我们应该继续读取

从管道中读取的第二个数据将类似,我们将读取消息的第二部分(
{70,71,72,73,74}
对应于
FGHIJ
),
namedPipeClient.IsMessageComplete
仍然是
false
表示消息不完整


当第三次从管道完成读取时,将只读取剩余的2个字节(
{75,76}
,对应于
KL
),但我们的缓冲区仍然有5个字节长,因此它看起来是这样的:(
{75,76,72,73,74}
对应于
KLHIJ
)。值
72、73、74仍然存在于循环的上一次迭代中。现在,将从
namedPipeClient.Read()
返回的值存储到
readCount
变量非常重要。它将包含值2,表明只有2字节的<代码> BytRead 缓冲区是有效的,其余字节应该被忽略。例如,“命名管道流失败”的标题,以及描述实际发生的情况和预期发生的情况的问题。希望这有帮助。@Richardisimo对不起,我不是来这里的。没问题,我只是想帮你。:)@如果IsMessageComplete做什么?我不太理解MSDN文档。另外,为什么我们需要使用readCount变量呢。它真正存储的是什么数据?顺便说一句,非常感谢much@Marc2001我给答案加了解释,老兄!你是我在网上遇到的最棒的人。非常感谢!你真的帮了我。
using (NamedPipeClientStream namedPipeClient = new NamedPipeClientStream(".", "test-pipe", PipeDirection.InOut))
{
    namedPipeClient.Connect();
    namedPipeClient.ReadMode = PipeTransmissionMode.Message;

    // StringBuilder is more efficient for string concatenation
    StringBuilder serverResponse = new StringBuilder();

    byte[] readBytes = new byte[5];

    do
    {
        // You need to store number of bytes read from pipe (to readCount variable).
        // It can be less then the length of readBytes buffer, in which case
        // GetString() would decode characters beyond end of message.
        var readCount = namedPipeClient.Read(readBytes, 0, readBytes.Length);
        var readText = Encoding.Default.GetString(readBytes, 0, readCount);

        // You original code "overwrites" content of serverResponse variable instead
        // of concatenating it to the previous value. So you would receive only 
        // the last part of the server message.
        serverResponse.Append(readText);

        // It is not needed to create new buffer, you can just reuse existing buffer
        //readBytes = new byte[5];

    // IsMessageComplete is now tested after read operation
    } while (!namedPipeClient.IsMessageComplete);

    System.Console.WriteLine(serverResponse.ToString());

    // You current server implementation exits as soon as it sends message to the client
    // and does not wait for incomming message. You'll have to change server accordingly 
    // to be able to send a message back to the server.
    //byte[] writeBytes = Encoding.Default.GetBytes("Hello from client!\n");
    //namedPipeClient.Write(writeBytes, 0, writeBytes.Length);
}