1. 程式人生 > >Windows程序間通訊—命名管道

Windows程序間通訊—命名管道

命名管道是通過網路來完成程序間的通訊,它遮蔽了底層的網路協議細節。我們在不瞭解網路協議的情況下,也可以利用命名管道來實現程序間的通訊。與Socket網路通訊相比,命名管道不再需要編寫身份驗證的程式碼。將命名管道作為一種網路程式設計方案時,它實際上建立了一個C/S通訊體系,並在其中可靠的傳輸資料。命名管道伺服器和客戶機的區別在於:伺服器是唯一一個有權建立命名管道的程序,也只有它能接受管道客戶機的連線請求。而客戶機只能同一個現成的命名管道伺服器建立連線。命名管道伺服器只能在WindowsNT或Windows2000上建立,不過可以是客戶機。命名管道提供了兩種基本通訊模式,位元組模式和訊息模式。在位元組模式中,資料以一個連續的位元組流的形式在客戶機和伺服器之間流動。而在訊息模式中,客戶機和伺服器則通過一系列不連續的資料單位進行資料的收發,每次在管道上發出一條訊息後,它必須作為一條完整的訊息讀入。

服務端程式碼流程:

1、建立命名管道:CreateNamedPipe

2、等待客戶端連線:ConnectNamedPipe

3、讀取客戶端請求資料:ReadFile

4、向客戶端回覆資料:WriteFile

5、關閉連線:DisconnectNamedPipe

6、關閉管道:CloseHandle

#include "stdafx.h"  
#include <windows.h>  
#include <strsafe.h>  
  
#define BUFSIZE 4096  
  
DWORD WINAPI InstanceThread(LPVOID);   
VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);   
  
int _tmain(VOID) { BOOL fConnected; DWORD dwThreadId; HANDLE hPipe, hThread; LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); // The main loop creates an instance of the named pipe and // then waits for a client to connect to it. When the client
// connects, a thread is created to handle communications // with that client, and the loop is repeated. for (;;) { hPipe = CreateNamedPipe( lpszPipename, // pipe name PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances BUFSIZE, // output buffer size BUFSIZE, // input buffer size 0, // client time-out NULL); // default security attribute if (hPipe == INVALID_HANDLE_VALUE) { printf("CreatePipe failed"); return 0; } // Wait for the client to connect; if it succeeds, // the function returns a nonzero value. If the function // returns zero, GetLastError returns ERROR_PIPE_CONNECTED. fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (fConnected) { // Create a thread for this client. hThread = CreateThread( NULL, // no security attribute 0, // default stack size InstanceThread, // thread proc (LPVOID) hPipe, // thread parameter 0, // not suspended &dwThreadId); // returns thread ID if (hThread == NULL) { printf("CreateThread failed"); return 0; } else CloseHandle(hThread); } else { // The client could not connect, so close the pipe. CloseHandle(hPipe); } } return 1; } DWORD WINAPI InstanceThread(LPVOID lpvParam) { TCHAR chRequest[BUFSIZE]; TCHAR chReply[BUFSIZE]; DWORD cbBytesRead, cbReplyBytes, cbWritten; BOOL fSuccess; HANDLE hPipe; // The thread's parameter is a handle to a pipe instance. hPipe = (HANDLE) lpvParam; while (1) { // Read client requests from the pipe. fSuccess = ReadFile( hPipe, // handle to pipe chRequest, // buffer to receive data BUFSIZE*sizeof(TCHAR), // size of buffer &cbBytesRead, // number of bytes read NULL); // not overlapped I/O if (! fSuccess || cbBytesRead == 0) break; printf((const char*)chRequest); GetAnswerToRequest(chRequest, chReply, &cbReplyBytes); // Write the reply to the pipe. fSuccess = WriteFile( hPipe, // handle to pipe chReply, // buffer to write from cbReplyBytes, // number of bytes to write &cbWritten, // number of bytes written NULL); // not overlapped I/O if (! fSuccess || cbReplyBytes != cbWritten) break; } // Flush the pipe to allow the client to read the pipe's contents // before disconnecting. Then disconnect the pipe, and close the // handle to this pipe instance. FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); return 1; } VOID GetAnswerToRequest(LPTSTR chRequest, LPTSTR chReply, LPDWORD pchBytes) { _tprintf( TEXT("%s\n"), chRequest ); StringCchCopy( chReply, BUFSIZE, TEXT("Default answer from server") ); *pchBytes = (lstrlen(chReply)+1)*sizeof(TCHAR); } /* 何問起 hovertree.com */

客戶端程式碼流程:

1、開啟命名管道:CreateFile

2、等待服務端響應:WaitNamedPipe

3、切換管道為讀模式:SetNamedPipeHandleState

4、向服務端發資料:WriteFile

5、讀服務端返回的資料:ReadFile

6、關閉管道:CloseHandle

#include "stdafx.h"  
#include <windows.h>  
#include <conio.h>  
  
  
#define BUFSIZE 512  
  
int _tmain(int argc, TCHAR *argv[])   
{   
    HANDLE hPipe;   
    LPTSTR lpvMessage=TEXT("Default message from client");   
    TCHAR chBuf[BUFSIZE];   
    BOOL fSuccess;   
    DWORD cbRead, cbWritten, dwMode;   
    LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");   
  
    if( argc > 1 )  
        lpvMessage = argv[1];  
  
    // Try to open a named pipe; wait for it, if necessary.   
  
    while (1)   
    {   
        hPipe = CreateFile(   
            lpszPipename,   // pipe name   
            GENERIC_READ |  // read and write access   
            GENERIC_WRITE,   
            0,              // no sharing   
            NULL,           // default security attributes  
            OPEN_EXISTING,  // opens existing pipe   
            0,              // default attributes   
            NULL);          // no template file   
  
        // Break if the pipe handle is valid.   
  
        if (hPipe != INVALID_HANDLE_VALUE)   
            break;   
  
        // Exit if an error other than ERROR_PIPE_BUSY occurs.   
  
        if (GetLastError() != ERROR_PIPE_BUSY)   
        {  
            printf("Could not open pipe");   
            return 0;  
        }  
  
        // All pipe instances are busy, so wait for 20 seconds.   
  
        if (!WaitNamedPipe(lpszPipename, 20000))   
        {   
            printf("Could not open pipe");   
            return 0;  
        }   
    }   
  
    // The pipe connected; change to message-read mode.   
  
    dwMode = PIPE_READMODE_MESSAGE;   
    fSuccess = SetNamedPipeHandleState(   
        hPipe,    // pipe handle   
        &dwMode,  // new pipe mode   
        NULL,     // don't set maximum bytes   
        NULL);    // don't set maximum time   
    if (!fSuccess)   
    {  
        printf("SetNamedPipeHandleState failed");   
        return 0;  
    }  // 何問起 hovertree.com
  
    // Send a message to the pipe server.   
  
    fSuccess = WriteFile(   
        hPipe,                  // pipe handle   
        lpvMessage,             // message   
        (lstrlen(lpvMessage)+1)*sizeof(TCHAR), // message length   
        &cbWritten,             // bytes written   
        NULL);                  // not overlapped   
    if (!fSuccess)   
    {  
        printf("WriteFile failed");   
        return 0;  
    }  
  
    do   
    {   
        // Read from the pipe.   
  
        fSuccess = ReadFile(   
            hPipe,    // pipe handle   
            chBuf,    // buffer to receive reply   
            BUFSIZE*sizeof(TCHAR),  // size of buffer   
            &cbRead,  // number of bytes read   
            NULL);    // not overlapped   
  
        if (! fSuccess && GetLastError() != ERROR_MORE_DATA)   
            break;   
  
        _tprintf( TEXT("%s\n"), chBuf );   
    } while (!fSuccess);  // repeat loop if ERROR_MORE_DATA   
  
    getch();  
  
    CloseHandle(hPipe);   
  
    return 0;   
}  

相關推薦

Windows程序通訊命名管道

命名管道是通過網路來完成程序間的通訊,它遮蔽了底層的網路協議細節。我們在不瞭解網路協議的情況下,也可以利用命名管道來實現程序間的通訊。與Socket網路通訊相比,命名管道不再需要編寫身份驗證的程式碼。將命名管道作為一種網路程式設計方案時,它實際上建立了一個C/S通訊體系,並在其中可靠的傳輸資料。命名管道伺服器

Visual C++網路程式設計經典案例詳解 第3章 多執行緒與非同步套接字程式設計 程序通訊 命名管道 命名管道例項

vc新增控制檯工程 名字命名管道例項 新增原始檔 名字 伺服器 #include<windows.h>                                //包含標頭檔案 #include<stdio.h> int main() {  

【linux開發】程序通訊命名管道-共享記憶體-記憶體對映-訊息佇列-訊號量

程序間通訊命名管道-共享記憶體-記憶體對映-訊息佇列-訊號量  在Unix平臺上,建立命名管道是建立了一個fifo檔案,和在shell下面用mkfifo命令的效果是一樣的。看起來這個管道檔案就是一個普通的檔案系統瓜掛載點,但是它只不過是作為一個名稱存在,實際的內容是一塊系統

【Linux】程序通訊-命名管道FIFO

命名管道概述 如果我們要在不相關的程序間交換資料,那麼使用FIFO檔案將會十分方便。 FIFO檔案通常也稱為命名管道(named pipe)。命名管道是一種特殊型別的檔案,它在檔案系統中以檔名的形式存在。 建立命名管道 建立命名管道一般有兩種方式: 命令列方式 一個比較舊

命名管道學習(簡單例程)----Windows程序通訊

管道(Pipe)實際是用於程序間通訊的一段共享記憶體,建立管道的程序稱為管道伺服器,連線到一個管道的程序為管道客戶機。通常我們把管道分為匿名管道和命名管道。但對於匿名管道的話,只能在本機上程序之間通訊,而且只能實現本地的父子程序之間的通訊,侷限性太大了。而這裡介紹的命名管道,就和匿名管道有些不同了,

Windows API 程序通訊管道(Pipe)

通過pipe程序間通訊**************************************//* 標頭檔案 */#include <windows.h> #include <stdio.h>#include <tchar.h>/* 常量 */#define PIPE

Linux:程序通訊管道通訊詳解

        在學習程序的時候,我們瞭解到了程序的獨立性:程序之間是相互獨立的,每個程序有自己的虛擬地址空間,並且虛擬地址空間通過頁表的對映,對映到屬於自己的實體記憶體上。並且各個程序之間互相不影響,執行自己的程式碼。    

php程序通訊--有名管道

管道PIPE   管道用於承載簡稱之間的通訊資料。為了方便理解,可以將管道比作檔案,程序A將資料寫到管道P中,然後程序B從管道P中讀取資料。php提供的管道操作API與操作檔案的API基本一樣,除了建立管道使用posix_mkfifo函式,讀寫等操作均與檔案操作函式相同。當然,你可以直接使用檔案

程序通訊管道--pipe和fifo使用

匿名管道pipe 函式原型: #include <unistd.h> int pipe(int fildes[2]); 引數說明 fildes是我們傳入的陣列,也是一個傳出引數。fildes[0]是讀端,fildes[1]是寫端。 返回值 成功呼叫返回0。 失敗呼叫返回-1且

Linux系統程式設計——程序通訊管道(pipe)

管道的概述 管道也叫無名管道,它是是 UNIX 系統 IPC(程序間通訊) 的最古老形式,所有的 UNIX 系統都支援這種通訊機制。 無名管道有如下特點: 1、半雙工,資料在同一時刻只能在一個方向上流動。 2、資料只能從管道的一端寫入,從另一端讀出。

Linux程序通訊——01管道

程序間通訊: 對於每個程序來說,都有一份屬於它自己的記憶體資源,並且獨佔這份記憶體資源。而程序間通訊的目的就是讓不同的程序間能看到一份公共的資源。所有交換的資料必須通過核心來傳遞,在核心中開闢一塊緩衝區,通過這塊緩衝區來實現資料的傳遞,核心提供的這種機制稱為程序間通訊。

Windows程序通訊-共享記憶體

#include "stdafx.h" #include "windows.h" //Name given to the pipe #define g_szPipeName "\\\\.\\Pipe\\MyNamedPipe" //Pipe name format - \\.\pipe\pipename

程序通訊管道通訊(PIPE匿名管道)

#include<stdio.h> #include<errno.h> #include<fcntl.h> #include<unistd.h> #include<stdlib.h> #include<string.h> int

程序通訊管道(pipe)

管道的概述 管道也叫無名管道,它是是 UNIX 系統 IPC(程序間通訊) 的最古老形式,所有的 UNIX 系統都支援這種通訊機制。 無名管道有如下特點: 1、半雙工,資料在同一時刻只能在一個方向上流動。 2、資料只能從管道的一端寫入,從另一端讀出。 3、寫入

Linux程序通訊之——管道(整理)

 程序間通訊 fork pipe pie_t 等用法(管道機制 通訊) 每個程序各自有不同的使用者地址空間,任 何一個程序的全域性變數在另一個程序中都看不到,所以程序之間要交換資料必須通過核心,在核心中開闢一塊緩衝 區,程序1把資料從使用者空間拷到核心緩衝區,程序2再從

Linux -- 程序通訊管道

管道是Linux裡的一種檔案型別,同時也是Linux系統下程序間通訊的一種方式 建立一個管道檔案有兩種方式: 1.  Shell 下命令 mkfifo + filename,即建立一個有名管道 2.

人工智慧(PythonNet)—— 程序通訊管道、訊息佇列、共享記憶體、訊號、訊號量、套接字)

一、程序間通訊        程序間通訊(IPC,InterProcess Communication)是指在不同程序之間傳播或交換資訊。        由於每個程序的空間是互相獨立的,程序之間無法互相直接獲取彼此的資源,故引入程序間通訊來實現程序間的資源互動。       

Windows程序通訊之共享記憶體

之前自己做的一個專案涉及到程序間通訊問題,我採用的是SOCKET方式。面試的時候有問過為什麼不採用其他方式。好吧,其實發現共享記憶體更方便一點。於是自己寫了一下,並且做了個測試介面。 寫的程式可以在這裡下載下載程式 程式啟動會獲得自身的視窗控制代碼,另外可以輸入一個視

Linux 程序通訊管道

程序之間的通訊之管道 目錄 1 無名管道    管道是一種最基本的IPC機制,作用於父子程序之間,完成資料傳遞。 管道有以下特性: 1.其本質是一個偽檔案(實為核心緩衝區)其本質是一個偽檔案(實為核心緩衝區) 2.由兩

Windows程序通訊的各種方法

程序是裝入記憶體並準備執行的程式,每個程序都有私有的虛擬地址空間,由程式碼、資料以及它可利用的系統資源(如檔案、管道等)組成。多程序/多執行緒是Windows作業系統的一個基本特徵。Microsoft Win32應用程式設計介面(Application Programming Interface, API)