SOFTIST 编程方法筆記 目録

命名管道通讯(簡易版)(VC++)

Named Pipe

利用命名管道进行进程间的数据通讯的笔记。基本流程是:
(1)服务器侧的进程调用CreateNamedPipe()函数来生成管道实体。
(2)服务器侧的进程调用ConnectNamedPipe()函数来等待(3)中记述的客户侧的连接。
(3)客户侧的进程调用CreateFile()函数来连接管道实体。
例:实体数为1的管道通讯。

服务器側的処理
1.创建命名管道,等待客户侧的连接。

HANDLE hPipeServer = INVALID_HANDLE_VALUE;
void CreatePipeServerSide()
{
    hPipeServer = CreateNamedPipe("\\\\.\\pipe\\test", 
                                               PIPE_ACCESS_DUPLEX, 
                                               PIPE_TYPE_BYTE | PIPE_WAIT, 1, 0, 0, 1000, 0);
    if(hPipeServer == INVALID_HANDLE_VALUE)
        return;

    if (!ConnectNamedPipe(hPipeServer, NULL))
    {
        CloseHandle(hPipeServer);
        hPipeServer = INVALID_HANDLE_VALUE;
    }
}
2.向管道写数据。
void WritePipeServerSide()
{
    if (hPipeServer != INVALID_HANDLE_VALUE)
    {
        char* buff = "Hi, I an the pipe server.";
        DWORD    nBytes;
        WriteFile(hPipeServer, buff, strlen(buff), &nBytes, NULL);
    }
}
3.从管道读数据。
void ReadPipeServerSide()
{
    if (hPipeServer != INVALID_HANDLE_VALUE)
    {
        DWORD    nBytes;
        char    buff[1024];
        memset(buff, NULL, sizeof(buff));
        if (ReadFile(hPipeServer, buff, 10, &nBytes, NULL))
            AfxMessageBox(buff);
    }
}
4.关闭管道。
void ClosePipeServerSide()
{
    if (hPipeServer != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hPipeServer);
        hPipeServer = INVALID_HANDLE_VALUE;
    }
}
客户侧側的処理
1.调用CreateFile()函数连接管道实体。
HANDLE hPipeClient = INVALID_HANDLE_VALUE;
void ConnectTestPipe()
{
    hPipeClient = CreateFile("\\\\.\\pipe\\test", GENERIC_READ | GENERIC_WRITE, 0, 0, 
                                      OPEN_EXISTING, 0, 0);
}
2.向管道写数据。
void WriteClientSide()
{
    if (hPipeClient != INVALID_HANDLE_VALUE)
    {
        DWORD nBytes;
        char* buff = "Hello, I am Client side of the Pipe.";
        WriteFile(hPipeClient, buff, strlen(buff), &nBytes, NULL);
    }
}
3.从管道读数据。
void ReadClientSide()
{
    if (hPipeClient != INVALID_HANDLE_VALUE)
    {
        DWORD    nBytes;
        char    buff[1024];
        memset(buff, NULL, sizeof(buff));
        if(ReadFile(hPipeClient, buff, 10, &nBytes, NULL))
            AfxMessageBox(buff);
    }
}
4.关闭管道。
void ClosePipeClientSide()
{
    if (hPipeClient != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hPipeClient);
        hPipeClient = INVALID_HANDLE_VALUE;
    }
}
注意:一般服务器侧的进程与客户侧的进程在不同的程序中执行。通讯处理放在线程里执行比较理想。测试時,通讯双方放在一个程序里也可。