3

I am trying to write string data from a C++ module to a C# module using Named Pipe.

My code is below:

C# (Pipe Server):

namespace CSPipe
{
    class Program
    {
        public void ThreadStartServer()
        {
            // Create a name pipe
            using (NamedPipeServerStream pipeStream = new NamedPipeServerStream("samplePipe"))
            {
                Console.WriteLine("[Server] Pipe created {0}", pipeStream.GetHashCode());

                // Wait for a connection
                pipeStream.WaitForConnection();
                Console.WriteLine("[Server] Pipe connection established");

                using (StreamReader sr = new StreamReader(pipeStream))
                {
                    string temp;
                    // We read a line from the pipe and print it together with the current time
                    while ((temp = sr.ReadLine()) != null)
                    {
                        Console.WriteLine("{0}: {1}", DateTime.Now, temp);
                    }
                }
            }

            Console.WriteLine("Connection lost");
            Console.ReadKey();
        }

        static void Main(string[] args)
        {
            Program Server = new Program();

            Thread ServerThread = new Thread(Server.ThreadStartServer);

            ServerThread.Start();

        }

    }

}

C++ (Pipe Client):

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>



int _tmain(int argc, _TCHAR* argv[])
{
      HANDLE hFile;
      BOOL flg;
      DWORD dwWrite;
      char szPipeUpdate[200];
      hFile = CreateFile(L"\\\\.\\pipe\\samplePipe", GENERIC_WRITE,
                                 0, NULL, OPEN_EXISTING,
                                  0, NULL);

      strcpy(szPipeUpdate,"Data from Named Pipe client for createnamedpipe");
      if(hFile == INVALID_HANDLE_VALUE)
      { 
          DWORD dw = GetLastError();
          printf("CreateFile failed for Named Pipe client\n:" );
      }
      else
      {
          while(1) 
          {
          flg = WriteFile(hFile, szPipeUpdate, strlen(szPipeUpdate),            &dwWrite, NULL);

          if (FALSE == flg)
          {
             printf("WriteFile failed for Named Pipe client\n");
          }
          else
          {
             printf("WriteFile succeeded for Named Pipe client\n");
          }
           FlushFileBuffers(hFile);
          // CloseHandle(hFile);
          }

      }
      getchar();
    return 0;
}

WriteFile() is returning immediately but the C# server is not getting any written pipe data. If I uncomment CloseHandle() in the C++ code then the C# Server gets the pipe data. I don't want to close and open the pipe every time I write data into the pipe. Is there any way that I can open the pipe only once and do WriteFile() whenever I have to write data into the pipe ?

Chris Hamilton
  • 555
  • 5
  • 22
Raveendra M Pai
  • 445
  • 2
  • 10
  • 27
  • 2
    Do you end your data with newline when writing to pipe? Because in C# server code you use ReadLine, which will block until it will receive newline (or until you close your pipe). – Evk Feb 27 '17 at 11:32
  • 1
    He doesn't - `strcpy(szPipeUpdate,"Data from Named Pipe client for createnamedpipe");`. Also if you really need to `FlushFileBuffers` after each write, consider using unbuffered I/O `FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH ` – mpiatek Feb 27 '17 at 11:42
  • Thanks a lot ! I got the cause of the issue. – Raveendra M Pai Feb 27 '17 at 11:44
  • It is caused by StreamReader, it tries to buffer too much data. This just isn't the right way to do it, if you want to transfer data as "packets" then you should change the pipe to message mode. – Hans Passant Feb 27 '17 at 12:20
  • what if I want to transfer data as structure ? – Raveendra M Pai Feb 27 '17 at 12:21

0 Answers0