如何使用命名管道(C ++服务器,C#客户端)

我正在尝试使用命名管道开始工作,因为我将来需要将它们用于我的项目。

目前,我有一台C ++服务器,等待客户端连接并通过测试消息发送。 我大致遵循本教程开始。 相关代码如下:

    #define MESSAGE L"TestMessage"

HANDLE hnamedPipe = INVALID_HANDLE_VALUE;

hnamedPipe = CreateNamedPipe(
    L"\.pipetestpipe",
    PIPE_ACCESS_DUPLEX,
    PIPE_TYPE_MESSAGE|
    PIPE_READMODE_MESSAGE|
    PIPE_WAIT,
    PIPE_UNLIMITED_INSTANCES,
    1024,
    1024,
    NMPWAIT_USE_DEFAULT_WAIT,
    NULL);

if(hnamedPipe == INVALID_HANDLE_VALUE)
{
        cout << "Failed" << endl;
}

while(true)
{
    cout<< "Waiting for client"<< endl;

    if(!ConnectNamedPipe(hnamedPipe,NULL))
    {
        if(ERROR_PIPE_CONNECTED != GetLastError())
        {
        cout << "FAIL"<< endl;
        }
    }

    cout<<"Connected!"<<endl;

    //Send over the message
    wchar_t chResponse[] = MESSAGE;
    DWORD cbResponse,cbWritten;
    cbResponse = sizeof(chResponse);

    if(!WriteFile(
    hnamedPipe,
    chResponse,
    cbResponse,
    &cbWritten,
    NULL))
    {
        wprintf(L"failiure w/err 0x%08lxn",GetLastError);
    }
    cout<<"Sent bytes :)" << endl;
}

客户端代码(C#)如下所示:

        using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut))
        {
            while (true)
            {
                Console.WriteLine("Connecting to server...");
                pipeClient.Connect();

                Console.WriteLine("Connected :)");
                Console.WriteLine(pipeClient.ReadByte());
                pipeClient.Close();
                Console.WriteLine("Closed");
            }

        }

目前,我已经让客户端成功连接到服务器,并打印出第一个字节。 我想知道如何做2件事:

  • 阅读完整的消息 - 我尝试在PipeClient上使用StreamReader来读取消息,但它无限期地挂在ReadLine()上。

  • 连续发送消息 - 我希望服务器在发送消息后将消息发送给客户端,客户端将一次一个地读取消息并将其打印出来。 我对IPC有点无知,所以起初我试图让客户端在while(true)循环中断开连接并重新连接到服务器,而服务器处于一段时间的真正循环中,在顶部始终等待新的客户端连接发送另一条消息。 我试图在上面的代码中。

  • 任何帮助,这将不胜感激。 最终的目标是将图像从服务器发送到客户端。 客户端然后将它们实时打印到屏幕上。 在我尝试图像数据之前,我想用简单的字符串消息来处理这个问题。

    编辑:

    最终,我希望能够从客户端向服务器发送消息,表明它想要获取最新的图像帧,然后服务器将发送最新的帧,然后客户端将在屏幕上显示该帧。 所以流程是:

  • 客户端 - >服务器:指示客户端需要最新的帧信息。 (很简单,也许是一个无符号整数,值为1)
  • 服务器 - >客户端:最新的框架信息。 (以RGB字节值存储在字节数组中的640x480图像)
  • 客户端:在显示器上显示框架。

  • ReadLine挂起,因为它正在等待你的测试消息不包括的换行符。

    如果您希望服务器持续发送消息,只需在WriteFile调用周围放置一个循环即可。 您不需要连接多次。 同样在客户端,围绕ReadLine放置循环。

    如果每条消息都包含由换行符终止的文本,那么这应该就足够了,但是如果您确实希望管道客户端在消息模式下工作,则需要调用:

    pipeClient.ReadMode = PipeTransmissionMode.Message;
    

    但是,我怀疑这会与StreamReader良好交互。 相反,您应该使用pipeClient.Read读取单个消息。

    更新

    回答你的新问题:

    在服务器上,一旦客户端连接,进入一个循环,其中:

  • 服务器从客户端读取数据。 这将阻塞,直到客户端请求一个帧。
  • 服务器发送一个帧。
  • 在客户端上,一旦它连接到服务器,就进入一个循环,其中:

  • 客户端发送“请发送帧”消息。
  • 客户端从服务器读取数据以获取帧。
  • 客户端显示框架。
  • 我不会使用消息模式管道。 如果帧的大小是固定的,那么客户端知道从服务器读取多少数据。 否则,在包含其长度的uint之前插入帧。

    链接地址: http://www.djcxy.com/p/48281.html

    上一篇: How to work with named pipes (C++ server , C# client)

    下一篇: Targeting multiple .NET frameworks in a single binary?