How to work with named pipes (C++ server , C# client)

I am trying to get started with working with named pipes as I will need to use them for a project of mine in the future.

At the moment I have a C++ server which waits until a client connects and sends over a test message. I roughly followed this tutorial to get started. The relevant code is below:

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

The client code (C#) is below:

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

        }

At the moment I have got the client to connect successfully to the server and it prints out the first byte. I want to know how to do 2 things:

  • Read the entire message - I tried using StreamReader over the pipeClient to read the message but it hangs on ReadLine() indefinitely.

  • Continuously send over messages - I want the server to send message after message to the client which will read them in one at a time and print them out. I am a bit clueless about IPC so at first I tried to make the client disconnect and reconnect to the server in the while(true) loop whilst the server is in a while true loop which at the top always waits for a new client connection before sending another message. My attempt at this is in the code above.

  • Any help with this would be greatly appreciated. Eventually the aim is to be sending over images from the server to the client. The client would then print them out to the screen in real-time. I wanted to get this working with simple string messages before I tried the image data.

    EDIT:

    Eventually I want to be able to send a message from the client to the server indicating it wants to get the latest image frame, the server will then send over the latest frame which the client will then display on screen. So the flow is:

  • Client -> Server : indicator that client wants the latest frame info. (Something simple, maybe an unsigned int with the value 1)
  • Server -> Client : Latest frame info. (640x480 image stored in a byte array with RGB byte values)
  • Client : Display the frame on the display.

  • ReadLine hangs because it is waiting for a newline, which your test message doesn't include.

    If you want the server to send messages continuously just put a loop round the WriteFile call. You don't need to connect more than once. Similarly in the client, put the loop around ReadLine .

    If each message consists of text terminated by a newline then that should suffice, but if you really want the pipe client to work in message mode you need to call:

    pipeClient.ReadMode = PipeTransmissionMode.Message;
    

    However, I doubt this would interact well with a StreamReader . Instead, you should read single messages using pipeClient.Read .

    Update

    To answer your new question:

    On the server, once the client has connected enter a loop in which:

  • The server does a read from the client. This will block until the client requests a frame.
  • The server sends a frame.
  • On the client, once it has connected to the server enter a loop in which:

  • The client sends a "please send a frame" message.
  • The client does a read from the server to get the frame.
  • The client displays the frame.
  • I wouldn't use a message mode pipe. If the frames are fixed in size then the client knows how much data to read from the server. Otherwise, precede the frame with a uint containing its length.

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

    上一篇: 命名管道示例

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