【IPC程式間通訊之一】郵槽MailSlot

Love_Hulidear發表於2014-05-14

IPC程式間通訊+郵槽MailSlot

      
        IPC(Inter-Process Communication,程式間通訊)。
       現代計算機採用虛擬記憶體機制,為程式提供獨立的足夠大的地址空間,處於安全目的,一個程式不具有特殊的許可權,是無法訪問另一個程式的記憶體空間,程式間相互隔絕。程式間通訊IPC就需要特別的機制來實現,郵槽MailSlot是常用的IPC方法之一。
        
       1.郵槽(MailSlot):
        
       郵槽MailSlot通訊的程式分為服務端客戶端。服務端建立MailSlot,建立時指定郵槽名,客戶端同過郵槽名開啟MailSlot。
       郵槽是單向的,服務端只能讀取MailSlot,客戶端只能寫入MailSlot。服務端讀取資料是先入先出,即先寫入的資料先被讀取。

        2.郵槽命名 :
        本機上格式:\\.\mailslot\[path\]name
        如:\\.mailslot\my_mailslot

       3.基本API函式
建立郵槽
        HANDLE  CreateMailSlot(
                          LPCTSTR  lpName,
                          DWORD     nMaxMessageSize,
                          DWORD     lReadTimeout,
                          LPSECURITY_ATTRIBUTES   lpSecurityAttributes );
        第一個引數:郵槽名。
        第二個引數:最大訊息長度。
        第三個引數:讀取超時,設為0時,沒有訊息立即返回,MAILSLOT_WAIT_FORVER時,一直等待訊息。
        第三個引數:安全屬性,一般設為NULL。
        該函式建立一個Mailslot,並返回該郵槽的控制程式碼。
讀取郵槽:       
        BOOL ReadFile(
                   
HANDLE    hFile,
                    LPVOID     lpBuffer,
                    DWORD    nNumberOfBytesToRead,
                    LPDOWRD    lpNumberOfBytesRead,
                    LPOVERLAPPED   lpOverlapped
);
        第一個引數:郵槽控制程式碼。
        第二個引數:快取地址。
        第三個引數:訊息的長度。
        第四個引數:實際讀取的長度。
        第五個引數:一般設定為NULL。
        該函式用於讀取郵槽內資料。
開啟郵槽:
        BOOL  CreateFile(
                     LPCTSTR   lpFileName,
                     DWORD     dwDesiredAccess,
                     DWORD     dwShareMode,
                     LPSECURITY_ATTRIBUTES   lpSecurityAttributes,
                     DWORD    dwCreationDisposition,
                     DWORD    dwFlagsAndAttributes,
                    HANDLE    hTemplateFile
);
         第一個引數:檔案指標。
         第二個引數:訪問模式。
         第三個引數:共享模式。
         第四個引數:安全屬性指標。
         第五個引數:建立選項。
         第六個引數:檔案屬性。
         第七個引數:用於複製檔案控制程式碼。
         該函式用於客戶端開啟Mailslot。
寫入郵槽:
        BOOL  WriteFile(
                     HANDLE    hFile,
                     LPCVOID   lpBuffer,
                     DWORD     nNumberOfBytesToWrite,
                     LPDWORD   lpNumberOfBytesWritten,
                     LPOVERLAPPED    lpOverlapped
);
         第一個引數:檔案控制程式碼。
         第二個引數:資料緩衝區指標。
         第三個引數:寫入位元組數。
         第四個引數:返回實際寫入位元組數。
         第五個引數:結構體指標,一般置NULL。
         該函式用於客戶端向Mailslot寫入資料。

         4.牛刀小試 : 
         先在VC6.0中執行服務端程式,在執行客戶端程式

        執行效果

Mailslot服務端:
#include 
#include 
/* 全域性變數 */
HANDLE hSlot;
//郵槽名
LPTSTR lpszSlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");
void main()
{ 
	DWORD  cbRead; 
	char lpszBuffer[256]=" ";  
	
    //建立郵槽
	hSlot = CreateMailslot(
		lpszSlotName,		        // mailslot 名
		0,							// 不限制訊息大小 
		MAILSLOT_WAIT_FOREVER,      // 無超時 
		(LPSECURITY_ATTRIBUTES) NULL); 
	printf("Mailslot 建立成功!\n");

	while(1)
	{

			// 讀取訊息
			ReadFile(hSlot,	    // mailslot控制程式碼
	        lpszBuffer,			// 快取
			256,			    // 訊息的長度
			&cbRead,			// 實際讀取的長度
			NULL); 

			// 顯示
			printf("Data from the mailslot: %s\n", lpszBuffer); 

	}
	return ; 
}
Mailslot客戶端:
#include 
#include 
/* 全域性變數 */
HANDLE hSlot;
LPTSTR lpszSlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");		// mailslot名
void main()
{ 
	HANDLE hFile; 
	DWORD cbWritten; 
    char *send_data="I from client!";

	// 開啟mailslot
	hFile = CreateFile(lpszSlotName, 
		GENERIC_WRITE,		// 可寫
		FILE_SHARE_READ,
		(LPSECURITY_ATTRIBUTES) NULL, 
		OPEN_EXISTING,		// 開啟一個已經存在的mailslot,應該由服務端已經建立
		FILE_ATTRIBUTE_NORMAL, 
		(HANDLE) NULL); 


	// 向mailslot寫入
	WriteFile(hFile, 
		send_data, 
		(DWORD) (lstrlen(send_data)+1)*sizeof(TCHAR),  
		&cbWritten, 
		(LPOVERLAPPED) NULL); 


	// 結束
	printf("Data written:%s\n",send_data); 
	CloseHandle(hFile); 
	return ;
}


相關文章