管道通訊初級

1. pipe管道通訊,其實socket也要依賴於它,能夠實現雙向通訊。還能解決併發。
比共享內存和郵槽都靠譜。
2. 禁止一個程序打開屢次,也就是鎖定一個程序只能打開一次,限制它的打開次數,用管道就    必須這麼作,不然會發生衝突。
3.有線程池也有管道池安全

4.例子服務器

  • 服務端
#include <stdio.h>
#include <Windows.h>

//管道是存在於操做系統
#define SIZE 4096
char pipename[128] = "\\\\.\\Pipe\\guandaopipe";    //用這種模式命名等同於設備。
HANDLE m_pipe = NULL;    //管道的句柄


//建立一個管道
void start()
{
    m_pipe = CreateNamedPipeA(
        pipename,    //管道名稱
        PIPE_ACCESS_DUPLEX,    //管道的讀寫屬性
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,        //消息模式,讀模式,等待模式(至關於阻塞模式)PIPE_TYPE_MESSAGE通常狀況有兩種,用的最多的是消息模式,另外一種是二進制模式(BYTE模式)。
        PIPE_UNLIMITED_INSTANCES,//同時開啓管道的最大個數,最可能是255,在服務器上能夠開闢更多。
        SIZE,    //輸出(讀)的緩衝區大小
        SIZE,    //輸出(寫)的緩衝區大小
        0,    //客戶端超時時間
        NULL
        );

        if (m_pipe == NULL)
        {
            printf("建立失敗");
            return;
        }

        //鏈接這個管道而且判斷是否連上。
        BOOL isconnect = ConnectNamedPipe(m_pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
        if (isconnect)
        {
            MessageBoxA(0, "connected OK", "connected OK", 0);
        }
        else
        {
            printf("建立失敗。");
        }
}

void read()
{
    char buf[SIZE] = { 0 };        //咱們有可能把管道的全部信息都讀了,初始化時原則上初始爲0。
    int last = 0;
    if (!ReadFile(m_pipe, buf, SIZE, &last, NULL))    //Readpipe是純C語言裏邊,若是是C的管道庫,用Readpipe,C語言把全部的設備當成文件來處理,因此用ReadFile,若返回值是0表示讀取失敗.
    {
        printf("讀取失敗");
        return;
    }
    printf("\nread%s", buf);
}

void write()
{
    char str[128] = "舉頭望明月,這就是管道。";
        int last = 0;
        BOOL res = WriteFile(m_pipe, str, sizeof(str), &last, NULL);
        if (!res)
        {
            printf("寫入失敗");
        }
}
void test()
{
    //先嚐試能不能打開,打開了,就說明原來存在。若是沒有打開就建立一個。
    HANDLE mutex = OpenMutexA(MUTEX_ALL_ACCESS, TRUE, "guandaoserver"); //把guandaoserver去掉就是匿名,就不能跨進程了。
        if (mutex == NULL)
        {//建立
            mutex = CreateMutexA(NULL, TRUE, "guandaoserver"); //若是是匿名就不能發揮做用了
        }
        else
        {
            MessageBoxA(0, "only one", "only one", 0);
            exit(0); //exit(0)表示正常退出,exit(x)都表示異常退出.
        }
}
//mutex是內核全部的進程都能讀到,限定程序只能打開一次。
void main()
{
    test();
    start();
    printf("服務器啓動\n");
    system("pause");
    write();
    system("pause");
    read();
    system("pause");
}

 

 

 

  • 客戶端
#include <stdio.h>
#include <Windows.h>

#define SIZE 4096
char pipename[128] = "\\\\.\\Pipe\\guandaopipe";    //用這種模式命名等同於設備。
HANDLE m_pipe = NULL;    //管道的句柄

void read()
{
    char buf[SIZE] = { 0 };        //咱們有可能把管道的全部信息都讀了,初始化時原則上初始爲0。
    int last = 0;
    if (!ReadFile(m_pipe, buf, SIZE, &last, NULL))    //Readpipe是純C語言裏邊,若是是C的管道庫,用Readpipe,C語言把全部的設備當成文件來處理,因此用ReadFile,若返回值是0表示讀取失敗.
    {
        printf("讀取失敗");
        return;
    }
    printf("\nread%s", buf);
}

void write()
{
    char str[128] = "又醜又傻多看書。";
    int last = 0;
    BOOL res = WriteFile(m_pipe, str, sizeof(str), &last, NULL);
    if (!res)
    {
        printf("寫入失敗");
    }
}

void main()
{
    //NMPWAIT_WAIT_FOREVER 經常使用到無限等待,表示若是沒有管道就一直卡着
    if (!WaitNamedPipeA(pipename, NMPWAIT_USE_DEFAULT_WAIT))
        //NMPWAIT_USE_DEFAULT_WAIT表示通常等待,只等一下
    {
        MessageBoxA(0, "connected NO", "connected NO", 0);
        return;
    }

    m_pipe = CreateFileA(pipename, //名稱
        GENERIC_WRITE | GENERIC_READ, //既能讀又能寫,是經過位運算符實現的。
        1, //表示是否共享,1表示獨有,0表示共有
        NULL, //默認安全屬性
        OPEN_EXISTING, //打開已經存在的
        FILE_ATTRIBUTE_NORMAL,//這兩個表示兩個默認的屬性
        NULL
        );

    

    system("pause");
    read();
    system("pause");
    write();
    system("pause");

}
相關文章
相關標籤/搜索