当前位置:   article > 正文

Windows/Linux平台下命名管道通信调用参考_windows使用命名管道通信

windows使用命名管道通信

在一些需要传递少量数据的进程通信业务中,采用命名管道通信是一种不错的选择,但是管道通信本身是不跨平台的。如果我们想在不同的平台下使用管道通信就会很麻烦。这里我简单的总结了一下命名管道在windows平台和Linux平台下的使用方法,希望对各位有所帮助。实现的比较简陋,大家可以根据自己的具体业务进行优化封装。

Windows平台管道通信调用

1.服务端创建管道

命名管道通信的服务端需要开辟一个线程,在线程里服务端创建命名管道,然后连接命名管道。通过管道服务端可以接收客户端发送过来的消息,也可以向客户端发送对应的消息。

  1. #include <Windows.h>
  2. bool StartServerPipeWorking()
  3. {
  4. while (true)
  5. {
  6. char buffer[1024];
  7. memset(buffer, 0x00, 1024);
  8. DWORD ReadNum;
  9. //创建命名管道
  10. HANDLE pipe_handle = CreateNamedPipe(L"\\\\.\\Pipe\\Ceshi",
  11. PIPE_ACCESS_DUPLEX,
  12. PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
  13. 1,
  14. 1024,
  15. 1024,
  16. 1000,
  17. NULL);
  18. if (pipe_handle == INVALID_HANDLE_VALUE)
  19. {
  20. continue;
  21. }
  22. //连接创建的命名管道
  23. if (ConnectNamedPipe(pipe_handle, NULL))
  24. {
  25. //等待读取管道中的内容
  26. if (ReadFile(pipe_handle, buffer, 1024, &ReadNum, NULL) == FALSE)
  27. {
  28. //读失败之后关闭对应的管道
  29. DisconnectNamedPipe(pipe_handle);
  30. CloseHandle(pipe_handle);
  31. continue;
  32. }
  33. //读取成功之后关闭对应的管道
  34. std::string input_string = std::string(buffer);
  35. std::cout << input_string;
  36. DisconnectNamedPipe(pipe_handle);
  37. CloseHandle(pipe_handle);
  38. }
  39. else
  40. {
  41. CloseHandle(pipe_handle);
  42. }
  43. }
  44. }

2.客户端连接管道进行通信

客户端在使用命名管道的时候,先检查一下对应的命名管道是否存在,如果不存在的话直接发送消息失败,如果存在的话会直接创建对应的管道文件,然后向管道中写入需要发送的数据。

  1. #include <Windows.h>
  2. bool SendPipeMsg(std::string input_str)
  3. {
  4. char buffer[1024];
  5. memset(buffer, 0x00, 1024);
  6. DWORD WriteNum;
  7. if (WaitNamedPipe(L"\\\\.\\Pipe\\Ceshi", 30000) == FALSE)
  8. {
  9. return false;
  10. }
  11. HANDLE hPipe = CreateFile(L"\\\\.\\Pipe\\Ceshi", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  12. if (hPipe == INVALID_HANDLE_VALUE)
  13. {
  14. return false;
  15. }
  16. if (WriteFile(hPipe, input_str.c_str(), input_str.length(), &WriteNum, NULL) == FALSE)
  17. {
  18. CloseHandle(hPipe);
  19. hPipe = INVALID_HANDLE_VALUE;
  20. return false;
  21. }
  22. CloseHandle(hPipe);
  23. return true;
  24. }

Linux平台管道通信调用

linux平台下的命名管道通信其实和Windows平台下的原理相同,就是在本地创建一个管道文件,然后通过读写管道文件实现进程间的通信。

1.服务端监听

服务端负责创建管道文件,然后监听管道文件中的消息变化,通过读取管道文件中的消息内容实现进程间通信

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. int receive_msg()
  8. {
  9. int fd,ret;
  10. //创建管道文件
  11. std::string fifo_path = "/home/test/test_fifo";
  12. ret = mkfifo(fifo_path.toStdString().c_str(), S_IFIFO|0666);
  13. if(ret == -1)
  14. {
  15. return -1;
  16. }
  17. //打开对应的管道文件
  18. fd = open(fifo_path.toStdString().c_str(), O_RDONLY);
  19. if(fd < 0)
  20. {
  21. return -2;
  22. }
  23. char recv[100] = {0};
  24. //读数据,命名管道没数据时会阻塞,有数据时就取出来
  25. read(fd, recv, sizeof(recv));
  26. std::string received_argument = std::string(recv);
  27. close(fd);
  28. }

2.客户端发送

客户端通过向管道文件中写入对应的内容实现和服务端的通信。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. int client_send_msg(string msg)
  8. {
  9. int handle;
  10. std::string fifo_path = "/home/test/test_fifo";
  11. handle = open(fifo_path.c_str(), O_WRONLY);
  12. if(handle < 0)
  13. {
  14. return 2;
  15. }
  16. write(handle, msg, msg.length());
  17. close(handle);
  18. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/576930
推荐阅读
相关标签
  

闽ICP备14008679号