赞
踩
在一些需要传递少量数据的进程通信业务中,采用命名管道通信是一种不错的选择,但是管道通信本身是不跨平台的。如果我们想在不同的平台下使用管道通信就会很麻烦。这里我简单的总结了一下命名管道在windows平台和Linux平台下的使用方法,希望对各位有所帮助。实现的比较简陋,大家可以根据自己的具体业务进行优化封装。
命名管道通信的服务端需要开辟一个线程,在线程里服务端创建命名管道,然后连接命名管道。通过管道服务端可以接收客户端发送过来的消息,也可以向客户端发送对应的消息。
- #include <Windows.h>
- bool StartServerPipeWorking()
- {
-
- while (true)
- {
- char buffer[1024];
- memset(buffer, 0x00, 1024);
- DWORD ReadNum;
- //创建命名管道
- HANDLE pipe_handle = CreateNamedPipe(L"\\\\.\\Pipe\\Ceshi",
- PIPE_ACCESS_DUPLEX,
- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
- 1,
- 1024,
- 1024,
- 1000,
- NULL);
- if (pipe_handle == INVALID_HANDLE_VALUE)
- {
- continue;
- }
- //连接创建的命名管道
- if (ConnectNamedPipe(pipe_handle, NULL))
- {
- //等待读取管道中的内容
- if (ReadFile(pipe_handle, buffer, 1024, &ReadNum, NULL) == FALSE)
- {
- //读失败之后关闭对应的管道
- DisconnectNamedPipe(pipe_handle);
- CloseHandle(pipe_handle);
- continue;
- }
- //读取成功之后关闭对应的管道
- std::string input_string = std::string(buffer);
- std::cout << input_string;
- DisconnectNamedPipe(pipe_handle);
- CloseHandle(pipe_handle);
- }
- else
- {
- CloseHandle(pipe_handle);
- }
- }
- }
客户端在使用命名管道的时候,先检查一下对应的命名管道是否存在,如果不存在的话直接发送消息失败,如果存在的话会直接创建对应的管道文件,然后向管道中写入需要发送的数据。
- #include <Windows.h>
- bool SendPipeMsg(std::string input_str)
- {
- char buffer[1024];
- memset(buffer, 0x00, 1024);
- DWORD WriteNum;
-
- if (WaitNamedPipe(L"\\\\.\\Pipe\\Ceshi", 30000) == FALSE)
- {
- return false;
- }
-
- HANDLE hPipe = CreateFile(L"\\\\.\\Pipe\\Ceshi", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hPipe == INVALID_HANDLE_VALUE)
- {
- return false;
- }
-
- if (WriteFile(hPipe, input_str.c_str(), input_str.length(), &WriteNum, NULL) == FALSE)
- {
- CloseHandle(hPipe);
- hPipe = INVALID_HANDLE_VALUE;
- return false;
- }
- CloseHandle(hPipe);
- return true;
- }
linux平台下的命名管道通信其实和Windows平台下的原理相同,就是在本地创建一个管道文件,然后通过读写管道文件实现进程间的通信。
服务端负责创建管道文件,然后监听管道文件中的消息变化,通过读取管道文件中的消息内容实现进程间通信。
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
-
- int receive_msg()
- {
- int fd,ret;
- //创建管道文件
- std::string fifo_path = "/home/test/test_fifo";
- ret = mkfifo(fifo_path.toStdString().c_str(), S_IFIFO|0666);
- if(ret == -1)
- {
- return -1;
- }
- //打开对应的管道文件
- fd = open(fifo_path.toStdString().c_str(), O_RDONLY);
- if(fd < 0)
- {
- return -2;
- }
- char recv[100] = {0};
- //读数据,命名管道没数据时会阻塞,有数据时就取出来
- read(fd, recv, sizeof(recv));
- std::string received_argument = std::string(recv);
- close(fd);
- }
客户端通过向管道文件中写入对应的内容实现和服务端的通信。
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
-
- int client_send_msg(string msg)
- {
- int handle;
- std::string fifo_path = "/home/test/test_fifo";
- handle = open(fifo_path.c_str(), O_WRONLY);
- if(handle < 0)
- {
- return 2;
- }
- write(handle, msg, msg.length());
- close(handle);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。