1. 程式人生 > >Windows核心程式設計之郵槽實現程序間通訊

Windows核心程式設計之郵槽實現程序間通訊

    郵槽是Windows系統提供的一種單向通訊的機制。即程序中的一方只能寫入或讀取資料,而另一方則只能讀取或寫入資料。通過郵槽,使用者可以實現一對多或跨網路的程序之間的通訊。但是,郵槽能傳輸的資料非常小,一般在400KB左右。如果使用者操作的資料過大,可能會導致郵槽不能正常工作。

1.建立郵槽

    使用者在實際程式設計時,可以使用Windows郵槽實現程序間通訊。但是使用者必須首先建立郵槽。在Windows系統中,使用者可以通過函式CreateMailslot函式建立郵槽。函式原型如下:

HANDLE CreateMailslotW(
    LPCWSTR lpName,
    DWORD nMaxMessageSize,
    DWORD lReadTimeout,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes
    );
    該函式的作用是建立郵槽並返回該郵槽的控制代碼。如果函式呼叫成功,將返回建立郵槽的控制代碼。否則,函式將返回INVALID_HANDLE_VALUE,表示郵槽建立失敗,引數說明如下:

    引數lpName表示郵槽的名稱。郵槽名稱的格式為“\\.\mailslot\name”。其中,name表示郵槽的名稱。使用者在c++開發環境中,應該將其指定為“\\\\.\\mailslot\\name”。如果使用者在不同的主機上執行程式,則需要把名稱字串中的“.”換成對方主機名稱。

    引數nMaxMessageSize 指定將通過郵槽傳送或接收的訊息的最大值,在實際程式設計中,一般將其設定為0,表示訊息的大小為任意值。

    引數lReadTimeout表示程式讀取操作的超時時間。如果該引數值為0,則當郵槽中沒有任何訊息時,該函式將立即返回。如果該函式值為MAILSLOT_WAIT_FOREVER,則表示該函式將等待,直到郵槽中有訊息函式才返回。

    引數lpSecurityAttributes是指向結構體LPSECURITY_ATTRIBUTES的指標,表示郵槽的安全屬性,一般情況下,將其設定為NULL,表示預設安全屬性。

    一般情況下,函式CreateMailslot常被用於程序通訊的服務方,客戶端方使用CreateFile函式開啟指定的郵槽,再進行相關操作。

2.操作郵槽

     使用者對郵槽進行操作包括將資料寫入郵槽和從郵槽中讀取資料等。在實際程式設計時,操作郵槽和操作檔案一樣,都是通過呼叫函式ReadFile()和WriteFile()進行讀寫操作。函式原型如下:

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

3.郵槽例項

服務端:

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

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE mail;												//定義郵槽控制代碼
	//建立郵槽
	mail=CreateMailslot("\\\\.\\mailslot\\my",0,MAILSLOT_WAIT_FOREVER,NULL);

	if(mail==INVALID_HANDLE_VALUE)								//判斷郵槽控制代碼
	{
		cout<<"建立郵槽失敗!\r\n";								//提示資訊
		return 0;
	}
	else
	{
		cout<<"建立郵槽成功,正在讀取資料……!\r\n";
		char text[200];												//定義字元陣列
		DWORD readtext;												//獲取實際讀取值
		while(1)
		{

			if(ReadFile(mail,text,200,&readtext,NULL))					//讀取資料
			{
				cout<<text<<endl;												//顯示資料
			}
		}
	}
	Sleep(100000);
	CloseHandle(mail);
	return 0;
}

客戶端:

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

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE mail2;												//定義郵槽控制代碼
	char text[]="您好,this is a message";						//初始化訊息
	DWORD writetext;											//獲取實際傳送值
	mail2=CreateFile("\\\\.\\mailslot\\my",GENERIC_WRITE,FILE_SHARE_READ,
		NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	//開啟檔案
	if(INVALID_HANDLE_VALUE==mail2)	
	{
		cout<<"郵槽開啟失敗!\r\n";
	}
	else
	{		 
		if(WriteFile(mail2,text,sizeof(text),&writetext,NULL))	//寫入資料
		{
			Sleep(1000);
			cout<<"資料寫入成功\r\n";								//資料寫入成功
		}
		else
		{
			cout<<"資料寫入失敗\r\n";
		}
		CloseHandle(mail2);											//關閉控制代碼
	}
	Sleep(10000);
	return 0;
}