1. 程式人生 > 實用技巧 >【遠端cmd通訊技術】筆記

【遠端cmd通訊技術】筆記

1.管道技術-Windows

管道是一種簡單的程序間通訊的技術。

管道就是一部份共享記憶體以便程序可以用來相互通訊,建立了Pipe核心物件的程序就是一個Pipe Server, 當另一個程序與這個程序建立的Pipe Server連線時,就稱為Pipe Client.當一個程序往Piple當中寫入資訊時,另一個程序便可以從這個Pipe讀出這個資訊。

管道可以分為命名管道和匿名管道。匿名管道比命名管道要簡單很多,他是一個未命名的單向管道,常用來在一個父程序和一個子程序之間傳遞資料,匿名管道只能實現本地機器上兩個程序的通訊,不能實現跨網路的通訊。
匿名管道由CreatePipe()函式建立,他的定義如下

  BOOL CreatePipe(
     PHANDLE hReadPipe, // 指向讀控制代碼的指標(指向HANDLE型別的指標,返回管道的讀控制代碼)
   PHANDLE hWritePipe, // 指向寫控制代碼的指標(指向HANDLE型別的指標,返回管道的寫控制代碼)
   LPSECURITY_ATTRIBUTES lpPipeAttributes, // 指向SECURITY_ATTRIBUTES結構體的指標,檢測返回的控制代碼是否能夠被子程序繼承。
   DWORD nSize // 指定管道的緩衝區大小,這裡賦值為0,使用系統預設大小的緩衝區
  ); 

SECURITY_ATTRIBUTES結構體定義如下:

typedef struct _SECURITY_ATTRIBUTES 
    {
   DWORD nLength;//結構體大小,可用sizeof取得
   LPVOID lpSecurityDescriptor; //指向一個物件的安全描述符 該安全描述符控制物件的共享 如果為NULL 則該物件使用呼叫程序的預設安全描述符 
   BOOL bInheritHandle;//安全描述的物件能否被新建立的程序繼承返回控制代碼 若為TRUE 則新程序繼承該控制代碼
   } SECURITY_ATTRIBUTES,        *PSECURITY_ATTRIBUTES;

一個匿名管道有兩頭,他們分別是讀控制代碼和寫控制代碼。寫控制代碼用來寫入資料,讀控制代碼用來讀取資料。我們分別呼叫ReadFile()和WriteFile() 就可以了。

BOOL ReadFile(
  HANDLE hFile,
  LPVOID lpBuffer,
  DWORD nNumberOfBytesToRead,
  LPDWORD lpNumberOfBytesRead, 
  LPOVERLAPPED lpOverlapped
  );
BOOL WriteFile(
      HANDLE hFile,
      LPCVOID lpBuffer,
      DOWRD nNumberOfBytesToWrite,
      LPOVERLAPPED lpOverlapped 
);

在讀取管道資料前,需要判斷管道是夠有資料存在。負責這個工作的函式是PeekNamedPipe(),其定義如下:

BOOL WINAPI PeekNamedPipe(
      HANDLE hNamedPipe, //管道控制代碼
      LPVOID lpBuffer, //讀取輸出緩衝區,可選,沒有資料是null
      DWORD nBufferSize, //緩衝區大小,如果上面那個是null,那就忽略這個
      LPDWORD lpBytesRead, //接收從管道中讀取資料的變數的指標,可選,此引數可以為NULL,如果沒有資料要讀取。
      LPDWORD lpTotalBytesAvail, //接收從管道讀取的位元組總數,此引數可以為NULL,如果沒有資料要讀取。
      LPDWORD lpBytesLeftThisMessage //返回該訊息中剩餘的位元組數,對於匿名管道可以為0
);