程序的位址空間是私有的。出于安全性的目的,如果一個程序不具有特殊的權限,是無法通路另外一個程序的記憶體空間的,也無法知道記憶體中儲存的資料的意義。但是在一些具體的應用情況下需要多個進行互相配合,有時計算機使用者也需要在多個應用程式之間交換資料。
Windows系統下,在程序間通信或共享資料的方式如下。
◇郵槽(Mailslot)。
郵槽是最為簡單的程序間資料共享方式,一個程序建立并擁有一個郵槽,其他程序都可以打開這個郵槽并向其發送消息。
◇管道(Pipe)。
實質是一種共享的記憶體,由一個程序建立,其他程序連接配接,并可進行雙向的通信。
◇剪貼闆(Clipboard)。
剪貼闆是重要的程序間資料共享方式,所有的程序都可以設定和修改剪貼闆,也都可以從剪貼闆擷取内容。
◇消息,具體是指WM_COPYDATA消息。
消息具有參數wParam和lParam。但是wParam和lParam最多是32位的。而WM_COPYDATA消息的參數不受wParam和lParam資料大小的限制,可以用于在程序間傳遞資料。
◇網絡。
網絡可以在不同主機上的不同程式間通信,當然也可以在相同主機上的不同程式間通信。
◇FileMapping[2]
一、郵槽(MailSlot)
使用郵槽通信的程序分為服務端和用戶端。郵槽由服務端建立,在建立時需要指定郵槽名,建立後服務端得到郵槽的句柄。在郵槽建立後,用戶端可以通過郵槽名打開郵槽,在獲得句柄後可以向郵槽寫入消息。
郵槽通信是單向的,隻有服務端才能從郵槽中讀取消息,用戶端隻能寫入消息。消息是先入先出的。用戶端先寫入的消息在服務端先被讀取。
通過郵槽通信的資料可以是任意格式的,但是一條消息不能大于424位元組。郵槽除了在本機内進行程序間通信外,在主機間也可以通信。但是在主機間進行郵槽通信,資料通過網絡傳播時使用的是資料報協定(UDP),是以是一種不可靠的通信。通過網絡進行郵槽通信時,用戶端必須知道服務端的主機名或域名。
MailSlot的詳細介紹,可以參見[3],[4]也作了一些介紹。
郵槽通信服務端程式

通過mailslot程序間通信-服務端
通過mailslot程序間通信
**************************************/
/* 頭檔案 */
#include <windows.h>
#include <stdio.h>
/* 全局變量 */
HANDLE hSlot;
LPTSTR lpszSlotName = TEXT("\\\\.\\mailslot\\sample_mailslot");
LPTSTR Message = TEXT("Message for mailslot in primary domain.");
/* ************************************
* void main()
* 功能 程序間mailslot通信用戶端
void main()
{
DWORD cbMessage, cMessage, cbRead;
BOOL fResult;
LPTSTR lpszBuffer;
TCHAR achID[80];
DWORD cAllMessages;
HANDLE hEvent;
OVERLAPPED ov;
cbMessage = cMessage = cbRead = 0;
hSlot = CreateMailslot(
lpszSlotName, // mailslot 名
0, // 不限制消息大小
MAILSLOT_WAIT_FOREVER, // 無逾時
(LPSECURITY_ATTRIBUTES) NULL);
if (hSlot == INVALID_HANDLE_VALUE)
printf("CreateMailslot failed with %d\n", GetLastError());
return ;
}
else printf("Mailslot created successfully.\n");
while(1)
// 擷取mailslot資訊
fResult = GetMailslotInfo(hSlot, // mailslot 句柄
(LPDWORD) NULL, // 無最大消息限制
&cbMessage, // 下一條消息的大小
&cMessage, // 消息的數量
(LPDWORD) NULL); // 無時限
if (!fResult)
printf("GetMailslotInfo failed with %d.\n", GetLastError());
if (cbMessage == MAILSLOT_NO_MESSAGE)
// 沒有消息,過一段時間再去讀
Sleep(20000);
continue;
cAllMessages = cMessage;
while (cMessage != 0) // 擷取全部消息,有可能不隻一條
// 提示資訊
wsprintf((LPTSTR) achID,
"\nMessage #%d of %d\n",
cAllMessages - cMessage + 1,
cAllMessages);
// 配置設定空間
lpszBuffer = (LPTSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
lstrlen((LPTSTR) achID)*sizeof(TCHAR) + cbMessage);
if( NULL == lpszBuffer )
// 讀取消息
fResult = ReadFile(hSlot, // mailslot句柄
lpszBuffer, // 緩存
cbMessage, // 消息的長度
&cbRead, // 實際讀取的長度
NULL);
printf("ReadFile failed with %d.\n", GetLastError());
GlobalFree((HGLOBAL) lpszBuffer);
// 處理資訊,顯示
lstrcat(lpszBuffer, (LPTSTR) achID);
printf("Contents of the mailslot: %s\n", lpszBuffer);
HeapFree(GetProcessHeap(),0,lpszBuffer);
// 計算剩餘的消息數
fResult = GetMailslotInfo(hSlot,
(LPDWORD) NULL,
&cbMessage,
&cMessage,
(LPDWORD) NULL);
printf("GetMailslotInfo failed (%d)\n", GetLastError());
郵槽通信用戶端程式

通過mailslot程序間通信-用戶端
LPTSTR lpszSlotName = TEXT("\\\\.\\mailslot\\sample_mailslot"); // mailslot名
LPTSTR lpszMessage = TEXT("Test Message for mailslot "); // 通信的内容
HANDLE hFile;
DWORD cbWritten;
DWORD cbMessage;
// 打開mailslot
hFile = CreateFile(lpszSlotName,
GENERIC_WRITE, // 可寫
FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING, // 打開一個已經存在的mailslot,應該由服務端已經建立
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hFile == INVALID_HANDLE_VALUE)
printf("CreateFile failed with %d.\n", GetLastError());
// 向mailslot寫入
fResult = WriteFile(hFile,
lpszMessage,
(DWORD) (lstrlen(lpszMessage)+1)*sizeof(TCHAR),
&cbWritten,
(LPOVERLAPPED) NULL);
printf("WriteFile failed with %d.\n", GetLastError());
// 結束
printf("Slot written to successfully.\n");
CloseHandle(hFile);
參考
[1] 精通Windows API 函數、接口、程式設計執行個體