国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
VC中的管道技術(shù)
VC中的管道技術(shù)

作者: 時間: 2004年9月27日 16:46:10 來源:天極網(wǎng)

 

      概述

管道(Pipe)實(shí)際是用于進(jìn)程間通信的一段共享內(nèi)存,創(chuàng)建管道的進(jìn)程稱為管道服務(wù)器,連接到一個管道的進(jìn)程為管道客戶機(jī)。命名管道(NamedPipes)是在管道服務(wù)器和一臺或多臺管道客戶機(jī)之間進(jìn)行單向或雙向通信的一種命名的管道。一個命名管道的所有實(shí)例共享同一個管道名,但是每一個實(shí)例均擁有獨(dú)立的緩存與句柄,并且為客戶——服務(wù)通信提供有一個分離的管道。實(shí)例的使用保證了多個管道客戶能夠在同一時間使用同一個命名管道。

Microsoft Windows NT、Windows 2000、Windows 95以及Windows98均提供對命名管道的支持(不包括Windows CE),但只有Windows NT和Windows2000才支持服務(wù)器端的命名管道技術(shù)。命名管道可以在同一臺計算機(jī)的不同進(jìn)程之間,或在跨越一個網(wǎng)絡(luò)的不同計算機(jī)的不同進(jìn)程之間進(jìn)行有連接的可靠數(shù)據(jù)通信,如果連接中斷,連接雙方都能立即收到連接斷開的信息。命令管道是圍繞Windows文件系統(tǒng)而設(shè)計的一種機(jī)制,采用的是命名管道文件系統(tǒng)(NamedPipe File System,NPFS)接口。對數(shù)據(jù)的收發(fā)也采用文件讀寫函數(shù)ReadFile()和WriteFile()來完成。在設(shè)計上,由于命名管道也利用了微軟網(wǎng)絡(luò)提供者(MSNP)重定向器,因此無需涉及底層的通信協(xié)議細(xì)節(jié)。命名管道還充分利用了Windows NT及Windows2000內(nèi)建的安全特性,通信的安全性相對較好。

  命名規(guī)范及通信模式

  每一個命名管道都有一個唯一的名字以區(qū)分于存在于系統(tǒng)的命名對象列表中的其他命名管道。管道服務(wù)器在調(diào)用CreateNamedPipe()函數(shù)創(chuàng)建命名管道的一個或多個實(shí)例時為其指定了名稱。對于管道客戶機(jī),則是在調(diào)用CreateFile()或CallNamedPipe()函數(shù)以連接一個命名管道實(shí)例時對管道名進(jìn)行指定。命名管道的命名規(guī)范與郵槽有些類似,對其標(biāo)識也是采用的UNC格式:

\\Server\Pipe\[Path]Name

  其中,第一部分\\Server指定了服務(wù)器的名字,命名管道服務(wù)即在此服務(wù)器創(chuàng)建,其字串部分可表示為一個小數(shù)點(diǎn)(表示本機(jī))、星號(當(dāng)前網(wǎng)絡(luò)字段)、域名或是一個真正的服務(wù);第二部分\Pipe與郵槽的\Mailslot一樣是一個不可變化的硬編碼字串,以指出該文件是從屬于NPFS;第三部分\[Path]Name則使應(yīng)用程序可以唯一定義及標(biāo)識一個命名管道的名字,而且可以設(shè)置多級目錄。

  命名管道提供了兩種基本的通信模式:字節(jié)模式和消息模式。可在CreateNamePipe()創(chuàng)建命名管道時分別用PIPE_TYPE_BYTE和PIPE_TYPE_MESSAGE標(biāo)志進(jìn)行設(shè)定。在字節(jié)模式中,信息以連續(xù)字節(jié)流的形式在客戶與服務(wù)器之間流動。這也就意味著,對于客戶機(jī)應(yīng)用和服務(wù)器應(yīng)用,在任何一個特定的時間段內(nèi),都無法準(zhǔn)確知道有多少字節(jié)從管道中讀出或?qū)懭搿T谶@種通信模式中,一方在向管道寫入某個數(shù)量的字節(jié)后,并不能保證管道另一方能讀出等量的字節(jié)。對于消息模式,客戶機(jī)和服務(wù)器則是通過一系列不連續(xù)的數(shù)據(jù)包進(jìn)行數(shù)據(jù)的收發(fā)。從管道發(fā)出的每一條消息都必須作為一條完整的消息讀入。

使用命名管道

管道服務(wù)器首次調(diào)用CreateNamedPipe()函數(shù)時,使用nMaxInstance參數(shù)指定了能同時存在的管道實(shí)例的最大數(shù)目。服務(wù)器可以重復(fù)調(diào)用CreateNamedPipe()函數(shù)去創(chuàng)建管道新的實(shí)例,直至達(dá)到設(shè)定的最大實(shí)例數(shù)。下面給出CreateNamedPipe()的函數(shù)原型:

HANDLE CreateNamedPipe(
 LPCTSTR lpName, // 指向管道名稱的指針
 DWORD dwOpenMode, // 管道打開模式
 DWORD dwPipeMode, // 管道模式
 DWORD nMaxInstances, // 最大實(shí)例數(shù)
 DWORD nOutBufferSize, // 輸出緩存大小
 DWORD nInBufferSize, // 輸入緩存大小
 DWORD nDefaultTimeOut, // 超時設(shè)置
 LPSECURITY_ATTRIBUTES lpSecurityAttributes // 安全屬性指針
);

如果在已定義超時值變?yōu)榱阋郧埃幸粋€實(shí)例管道可以使用,則創(chuàng)建成功并返回管道句柄,以此偵聽來自客戶機(jī)的連接請求。另一方面,客戶機(jī)通過函數(shù)WaitNamedPipe()使服務(wù)器進(jìn)程等待來自客戶的實(shí)例連接。如果在超時值變?yōu)榱阋郧?,有一個管道可供連接使用,則函數(shù)將成功返回,并通過調(diào)用CreateFile()或CallNamedPipe()來呼叫對服務(wù)器的連接。此時服務(wù)器將接受客戶的連接請求,成功建立連接,服務(wù)器調(diào)用的等待客戶機(jī)建立連接的ConnectNamedPipe()函數(shù)也將成功返回。

  從調(diào)用時序上看,首先是客戶機(jī)通過WaitNamedPipe()使服務(wù)器的CreateFile()在限時時間內(nèi)創(chuàng)建實(shí)例成功,然后雙方通過ConnectNamedPipe()和CreateFile()成功連接,在返回用以通信的文件句柄后,客戶、服務(wù)雙方即可進(jìn)行通信。

  在建立了連接后,客戶機(jī)與服務(wù)器即可通過ReadFile()和WriteFile()并利用得到的管道句柄,以文件讀寫的形式彼此間進(jìn)行信息交換。當(dāng)客戶與服務(wù)器的通信結(jié)束,或是由于某種原因一方需要斷開時,由客戶機(jī)調(diào)用CloseFile()函數(shù)關(guān)閉打開的管道句柄,服務(wù)器隨即調(diào)用DisconnectNamedPipe()函數(shù)。當(dāng)然,服務(wù)器也可以通過單方面調(diào)用DisconnectNamedPipe()來終止連接。在終止連接后調(diào)用函數(shù)CloseHandle()來關(guān)閉此管道。下面給出的程序清單即是按照上述方法實(shí)現(xiàn)的命名管道服務(wù)器和客戶機(jī)進(jìn)行通信的簡單程序?qū)崿F(xiàn)代碼:
服務(wù)器端:

m_hPipe= CreateNamedPipe("\\\\.\\Pipe\\Test", PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, 0, 0, 1000, NULL); // 創(chuàng)建命名管道
if (m_hPipe == INVALID_HANDLE_value)
 m_sMessage = "創(chuàng)建命名管道失敗!";
else{
 m_sMessage = "成功創(chuàng)建命名管道!";
 AfxBeginThread(ReadProc, this); // 開啟線程
}

  由于ConnectNamedPipe()函數(shù)在沒有客戶機(jī)連接到服務(wù)器時會無限等待下去,因此為避免由此引起主線程的阻塞,為其開辟了一個子線程ReadProc:

UINT ReadProc(LPVOID lpVoid)
{
 char buffer[1024]; // 數(shù)據(jù)緩存
 DWORD ReadNum;
 CServerView* pView = (CServerView*)lpVoid; // 獲取視句柄
 if (ConnectNamedPipe(pView->m_hPipe, NULL) == FALSE) // 等待客戶機(jī)的連接
 {
  CloseHandle(pView->m_hPipe); // 關(guān)閉管道句柄
  pView->m_sMessage = "與客戶機(jī)建立連接失敗!"; // 顯示信息
  pView->Invalidate();
  return 0;
 }else{
  pView->m_sMessage = "與客戶機(jī)建立連接!"; // 顯示信息
  pView->Invalidate();
 }
 // 從管道讀取數(shù)據(jù)
 if (ReadFile(pView->m_hPipe, buffer, sizeof(buffer), &ReadNum, NULL) == FALSE)
 {
  CloseHandle(pView->m_hPipe); // 關(guān)閉管道句柄
  pView->m_sMessage = "從管道讀取數(shù)據(jù)失敗!"; // 顯示信息
  pView->Invalidate();
 } else {
  buffer[ReadNum] = '\0'; // 顯示接收到的信息
  pView->m_sMessage = CString(buffer);
  pView->Invalidate();
 }
 return 1;
}

  在客戶同服務(wù)器建立連接后,ConnectNamedPipe()才會返回,其下語句才得以執(zhí)行。隨后的ReadFile()將負(fù)責(zé)把客戶寫入管道的數(shù)據(jù)讀取出來。在全部操作完成后,服務(wù)器可以通過調(diào)用函數(shù)DisconnectNamedPipe()而終止連接:

if (DisconnectNamedPipe(m_hPipe) == FALSE) // 終止連接
 m_sMessage = "終止連接失敗!";
else
{
 CloseHandle(m_hPipe); // 關(guān)閉管道句柄
 m_sMessage = "成功終止連接!";
}

  客戶機(jī)端:

CString Message = "[測試數(shù)據(jù),由客戶機(jī)發(fā)出]"; // 要發(fā)送的數(shù)據(jù)
DWORD WriteNum; // 發(fā)送的是數(shù)據(jù)長度
// 等待與服務(wù)器的連接
if (WaitNamedPipe("\\\\.\\Pipe\\Test", NMPWAIT_WAIT_FOREVER) == FALSE)
{
 m_sMessage = "等待連接失敗!"; // 顯示信息
 Invalidate();
 return;
}
// 打開已創(chuàng)建的管道句柄
HANDLEhPipe = CreateFile("\\\\.\\Pipe\\Test", GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hPipe == INVALID_HANDLE_value)
{
 m_sMessage = "管道打開失敗!"; // 顯示信息
 Invalidate();
 return;
} else {
 m_sMessage = "成功打開管道!"; // 顯示信息
 Invalidate();
}
// 向管道寫入數(shù)據(jù)
if (WriteFile(hPipe, Message, Message.GetLength(), &WriteNum, NULL) == FALSE)
{
 m_sMessage = "數(shù)據(jù)寫入管道失敗!"; // 顯示信息
 Invalidate();
} else {
 m_sMessage = "數(shù)據(jù)成功寫入管道!"; // 顯示信息
 Invalidate();
}
CloseHandle(hPipe); // 關(guān)閉管道句柄 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
淺談 windows 命名管道
郵槽
孫鑫VC視頻教程筆記之第十七課“進(jìn)程間的通信”
MFC 中獲得各個類的指針/句柄 ID的總結(jié)(轉(zhuǎn))
形形色色的自定義消息(下)
hadoop rpc 實(shí)例
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服