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

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

I currently have a C ++ server waiting for a client to connect and send a test message. I started following this tutorial to get started. Relevant code below:

    #define MESSAGE L"TestMessage"

HANDLE hnamedPipe = INVALID_HANDLE_VALUE;

hnamedPipe = CreateNamedPipe(
    L"\\\\.\\pipe\\testpipe",
    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%08lx\n",GetLastError);
    }
    cout<<"Sent bytes :)" << endl;
}

      

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 a client to connect to the server successfully and it outputs the first byte. I want to know how to do 2 things:

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

  • Constantly send messages - I want the server to send a message after the message to the client, which will read them one at a time and print them out. I am a bit unaware of IPC, so I first tried to get the client to disconnect and reconnect to the server in a while (true) loop while the server is while the true loop at the top is always waiting 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. Ultimately, the goal is to send images from the server to the client. The client will then display them on the screen in real time. I wanted this to work with simple string messages before I tried image data.

EDIT:

Eventually I want to be able to send a message from the client to the server indicating that it wants the last frame of the image, then the server will send the last frame that the client will display on the screen. So the flow:

  • Client -> Server: Indicator that the client wants the latest frame information. (Something simple, perhaps unsigned int with a value of 1)
  • Server -> Client: Latest frame information. (640x480 image stored in a byte array with RGB byte values)
  • Client: Display the frame on the display.
+3


source to share


1 answer


ReadLine

hangs because it is waiting for a new line that does not include the test message.

If you want the server to keep sending messages all the time, just put a loop around the call WriteFile

. You don't need to connect more than once. Likewise, in the client, put a loop around ReadLine

.

If each message consists of newline-terminated text, that should be sufficient, but if you really want the channel client to be in message mode, you need to call:

pipeClient.ReadMode = PipeTransmissionMode.Message;

      

However, I doubt it would interact well with StreamReader

. Instead, you should read single messages using pipeClient.Read

.

Update



To answer a new question:

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

  • The server is reading from the client. This will block until the client requests a frame.
  • The server is sending the frame.

On the client, when it has connected to the server, enter a loop where:

  • The client sends a message "please send a frame".
  • The client reads from the server to get the frame.
  • The client renders the frame.

I would not use the message mode channel. If the frames are fixed in size, then the client knows how much data to read from the server. Otherwise, the frame is preceded by a uint containing its length.

+4


source







All Articles