2013年10月1日 星期二

[named pipe教學] 讓C++和C#的程序互相溝通(IPC) 附程式碼

pipe的用途是讓同一台電腦上的兩個不同的process在執行時互相溝通,或是讓不同網路的兩台電腦互相溝通,大多數作業系統,如Linux、Free BSD、windows都各自有自己的pipe的API,本文以windows為主

windows上的pipe有兩種
1. anonymous pipe
2. named pipe

顧名思義,前者的pipe沒有名字,後者有名字
anonymous pipe主要用在parent process和child process之間的溝通,但只能用在單一電腦上。至於named pipe就比較強大,可以用在跨網路上

本文以windows上的named pipe為範例

C# server
using System.IO.Pipes;

using (NamedPipeServerStream pipeStream = new NamedPipeServerStream("mypipe"))
                {
                    pipeStream.WaitForConnection();
                    StreamReader sr = new StreamReader(pipeStream);                  
                 
                    string tmp;
                    while ((tmp = sr.ReadLine()) != null)                                          
                        pipeMsg.Text += tmp + "\r\n";
                 
                }


C++ client

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

hFile = CreateFile("//./pipe/mypipe", GENERIC_WRITE,
                         FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, OPEN_EXISTING,
                     FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
DWORD dw = GetLastError();
printf("CreateFile failed for Named Pipe client\n:" );
break;
}
else
{
flg = WriteFile(hFile, s.c_str(), s.length(), &dwWrite, NULL);
if (FALSE == flg)
printf("WriteFile failed for Named Pipe client\n");

CloseHandle(hFile);
}
C#已經把windows的named pipe API包得好好的,因此程式碼看起來比較平易近人。
至於C++這邊要注意的是,連到named  pipe時的路徑,要在pipe名稱前面加上
//./pipe/
否則會連不上唷

以下為完整可編譯的專案 (VS 2012)
https://docs.google.com/file/d/0Byr8Dpnq_aK8cUN3UjhPbUdsTUE/edit?usp=sharing


參考資料
http://www.cnblogs.com/yukaizhao/archive/2011/08/04/system-io-pipes.html