c++下使用邮槽实现进程间通信

  Windows API提供了邮槽和命名管道两种机制来实现进程间通信,在这里使用C++实现邮槽。

  邮槽是Windows提供的一种进程间单向通信的机制,进程中的一方只能读取(或写入)数据,而另一方只能写入(或读取)数据。这种进程间的通信可以发生在本地或者网络之中。而在使用邮槽之前,服务器端必须先创建邮槽,创建的函数原型如下:

1 HANDLE WINAPI CreateMailslot(
2   _In_     LPCTSTR               lpName,
3   _In_     DWORD                 nMaxMessageSize,
4   _In_     DWORD                 lReadTimeout,
5   _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes
6 );

  其中参数lpName表示邮槽的名称。邮槽名称的格式为"\\.\mailslot\YourMailslotName",其中YourMailslotName由用户指定。需要注意的是,在实际编码中反斜杠需要转义;参数nMaxMessageSize表示发送的消息大小的最大值,若设置为0则表示大小为任意值。(实际上邮槽能传输的数据非常小,一般400KB,若数据过大,邮槽可能无法正常工作);参数lReadTimeout表示读取操作的超时时间;参数lpSecurityAttributes表示邮槽的安全属性,置为NULL表示使用默认的安全属性。

  客户端在使用邮槽前必须先打开邮槽,通过函数CreateFile()实现,函数原型如下:

1 HANDLE WINAPI CreateFile(
2   _In_     LPCTSTR               lpFileName,
3   _In_     DWORD                 dwDesiredAccess,
4   _In_     DWORD                 dwShareMode,
5   _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
6   _In_     DWORD                 dwCreationDisposition,
7   _In_     DWORD                 dwFlagsAndAttributes,
8   _In_opt_ HANDLE                hTemplateFile
9 );

  参数的具体设置方法可参考MSDN给出的解释:

  https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx

  需要注意的是,指定要打开的邮槽时,若程序是在不同主机上运行的,邮槽名称中的点号"."需要改成对方主机的名称。

  在实际的编程过程中,对邮槽的操作与文件一样,都是通过调用函数ReadFile()和WriteFile()实现的,函数原型如下:

 1 BOOL WINAPI ReadFile(
 2   _In_        HANDLE       hFile,
 3   _Out_       LPVOID       lpBuffer,
 4   _In_        DWORD        nNumberOfBytesToRead,
 5   _Out_opt_   LPDWORD      lpNumberOfBytesRead,
 6   _Inout_opt_ LPOVERLAPPED lpOverlapped
 7 );
 8
 9 BOOL WINAPI WriteFile(
10   _In_        HANDLE       hFile,
11   _In_        LPCVOID      lpBuffer,
12   _In_        DWORD        nNumberOfBytesToWrite,
13   _Out_opt_   LPDWORD      lpNumberOfBytesWritten,
14   _Inout_opt_ LPOVERLAPPED lpOverlapped
15 );

  其中参数lpNumberOfBytesWritten是一个指向DWORD类型的指针,表示实际读取/写入的字节数。

  最终实现的代码如下,实现面向对象的方法实现:

  服务器端:

 1 //header.h
 2 #ifndef HEADER_H
 3 #define HEADER_H
 4
 5 #include <windows.h>
 6
 7 #define BUFFER_SIZE 1024
 8
 9 class MailServer
10 {
11 public:
12     MailServer();
13     MailServer(const MailServer &) = delete;
14     MailServer & operator=(const MailServer &) = delete;
15     ~MailServer();
16     void ReadMail();
17 private:
18     HANDLE h_mail;
19     char buffer[BUFFER_SIZE];
20     DWORD exact_read_num; //指向实际读取的字节数的指针
21 };
22
23 #endif
 1 //definition.cpp
 2 #include "header.h"
 3 #include <iostream>
 4
 5 MailServer::MailServer()
 6 {
 7     //邮槽的命名格式为"\\.\mailslot\YourMailslotName",反斜杠需要转义,采用非阻塞式读取方法
 8     h_mail = ::CreateMailslot("\\\\.\\mailslot\\MyMailSlot", 0, 0, nullptr);
 9     if (h_mail == INVALID_HANDLE_VALUE)
10     {
11         std::cerr << "Failed to create a mailslot!\n";
12         ::system("pause");
13         exit(1);
14     }
15     else
16     {
17         std::cout << "Mailslot created successfully..." << std::endl;
18     }
19 }
20
21 MailServer::~MailServer()
22 {
23     ::CloseHandle(h_mail);
24     std::cout << "Mailslot closed..." << std::endl;
25 }
26
27 void MailServer::ReadMail()
28 {
29     std::cout << "Reading mail from mailslot..." << std::endl;
30     while (true)
31     {
32         if (::ReadFile(h_mail, buffer, BUFFER_SIZE, &exact_read_num, nullptr))
33         {
34             std::cout << "New mail: " << buffer << std::endl;
35         }
36     }
37 }
 1 //server.cpp
 2 #include "header.h"
 3
 4 int main()
 5 {
 6     MailServer mail_svr;
 7     mail_svr.ReadMail();
 8     system("pause");
 9     return 0;
10 }

  客户端:

 1 //header.h
 2 #ifndef HEADER_H
 3 #define HEADER_H
 4
 5 #include "windows.h"
 6
 7 #define BUFFER_SIZE 1024
 8
 9 class MailClient
10 {
11 public:
12     MailClient();
13     MailClient(const MailClient &) = delete;
14     MailClient & operator=(const MailClient &) = delete;
15     ~MailClient();
16     void SendMail();
17 private:
18     HANDLE h_mail;
19     char buffer[BUFFER_SIZE];
20     DWORD exact_write_num;
21 };
22
23 #endif
 1 //definition.cpp
 2 #include "header.h"
 3 #include <iostream>
 4
 5 MailClient::MailClient()
 6 {
 7     h_mail = ::CreateFile("\\\\.\\mailslot\\MyMailSlot", GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
 8     if (h_mail == INVALID_HANDLE_VALUE)
 9     {
10         std::cerr << "Failed to create a mailslot!\n";
11         system("pause");
12         exit(1);
13     }
14     else
15     {
16         std::cout << "Mailslot created successfully..." << std::endl;
17     }
18 }
19
20 MailClient::~MailClient()
21 {
22     ::CloseHandle(h_mail);
23     std::cout << "Mailslot closed..." << std::endl;
24 }
25
26 void MailClient::SendMail()
27 {
28     while (true)
29     {
30         std::cout << "Please write a mail: " << std::flush;
31         std::cin.getline(buffer, BUFFER_SIZE);
32         if (strcmp(buffer, "exit") == 0)
33         {
34             std::cout << "User requests to close the mailslot..." << std::endl;
35             break;
36         }
37         else
38         {
39             if (::WriteFile(h_mail, buffer, BUFFER_SIZE, &exact_write_num, nullptr))
40             {
41                 std::cout << "Mail sent successfully..." << std::endl;
42             }
43             else
44             {
45                 std::cerr << "Failed to send the mail...\n";
46                 system("pause");
47                 exit(1);
48             }
49         }
50     }
51 }
1 #include "header.h"
2
3 int main()
4 {
5     MailClient mail_clt;
6     mail_clt.SendMail();
7     system("pause");
8     return 0;
9 }
时间: 2024-11-10 07:11:23

c++下使用邮槽实现进程间通信的相关文章

两个程序之间的通行(邮槽)

*Windows环境下,实现进程间的通信方式消息.命名管道(Name Pipes).剪贴板(ClipBoard)等,邮槽(MailSlot)也是其中一种. 1.邮槽 邮槽(Mailslot)也称为邮件槽,它是 Windows 提供的一种用来实现进程间通信的手段,是单向数据传输的服务. 邮槽的弊端:邮槽是单向通信.服务器端只能读取,客户端只能写入.如果要双向通信就需要服务端写一个邮槽,客户端在写一个邮槽.创建两个邮槽. 服务端和客户端的区分:创建邮槽的为服务端,已存在的邮槽的哪一端. 客户端在使用

【IPC进程间通讯之一】邮槽MailSlot

IPC进程间通信+邮槽MailSlot         IPC(Inter-Process Communication,进程间通信).        现代计算机采用虚拟内存机制,为进程提供独立的足够大的地址空间,处于安全目的,一个进程不具有特殊的权限,是无法访问另一个进程的内存空间,进程间相互隔绝.进程间通信IPC就需要特别的机制来实现,邮槽MailSlot是常用的IPC方法之一.                 1.邮槽(MailSlot):                 邮槽MailSlo

c++下使用命名管道实现进程间通信

前面已经使用邮槽实现过进程间通信:http://www.cnblogs.com/jzincnblogs/p/5192654.html ,这里使用命名管道实现进程间通信. 与邮槽不同的是,命名管道在进程间传输数据是基于连接且可靠的传输方式,所以命名管道传输数据只能一对一.使用命名管道的步骤如下: ①创建命名管道,命名管道通过调用函数CreateNamedPipe()创建,函数原型如下: 1 HANDLE WINAPI CreateNamedPipe( 2 _In_ LPCTSTR lpName,

邮槽 匿名管道 命名管道 剪贴板 进程通讯 转自http://www.cnblogs.com/kzloser/archive/2012/11/04/2753367.html#

邮槽 通信流程: 服务器 客户端 注意: 邮槽是基于广播通信体系设计出来的,它采用无连接的不可靠的数据传输 邮槽可以实现一对多的单向通信,我们可以利用这个特点编写一个网络会议通知系统,而且实现这一的系统所需要编写的代码非常少.如果读者是项目经理,就可以给你手下每一位员工的机器上安装上这个系统中的邮槽服务器端程序,在你自己的机器上安装油槽的客户端程序,这样,当你想通知员工开会,就可以通过自己安装的邮槽客户端程序.将开会这个消息发送出去,因为机器上都安装了邮槽服务器端的程序,所以他们都能同时收到你发

windows 邮槽mailslot 在服务程序内建立后客户端无权限访问(GetLastError() == 5)的问题

邮槽创建在服务程序内,可以创建成功, 但外部客户端连接时 m_hMailslot = CreateFile("\\\\.\\mailslot\\zdpMailslot",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);GetLastError返回错误 5 ,无权限访问Access Denied 如果路径改为 \\\\*\\mailslot\\zdpMailslot \\\\comp

进程间的通信——邮槽与命名管道d

进程间的通信是指在系统中两个或多个进程之间通过第三方进行数据共享. 1.邮槽. 邮槽是window系统提供的一种单向通信的机制.即进程中的一方只能写入或者读取数据,而另一方则只能读取或写入数据.通过邮槽,可以实现一对多或跨网络的进程之间的通信.但邮槽传输的数据量非常小,一般只有400KB左右. 邮槽创建函数CreateMailslot,函数原型: HANDLE CreateMailslot( LPCTSTR lpName, // mailslot name DWORD nMaxMessageSi

77.邮槽通信

服务器端 创建邮槽 1 //名称,数量 等待时间 安全属性 2 HANDLE hmailslot = CreateMailslotA(MAILSLOT, 0, MAILSLOT_WAIT_FOREVER, NULL); 获取邮槽信息 1 DWORD dxNextsize = 0;//标识最大的数据大小 2 DWORD dxmsgcount = 0;//消息数量 3 DWORD readcount = 0;//读取成功的数量 4 5 //获取邮槽信息 6 //文件名 标记最大的数据大小 多少条消息

[转]Windows环境下利用“共享内存”实现进程间通信的C/C++代码---利用CreateFileMapping和MapViewOfFile

http://blog.csdn.net/stpeace/article/details/39534361 进程间的通信方式有很多种, 上次我们说了最傻瓜的“共享外存/文件”的方法. 那么, 在本文中, 我们即将学习“共享内存”的方式实现进程间的通信, 这是IPC最快的方法.有的地方又把这种“共享内存”的方式叫做“内存映射文件”方式. 我们首先来看看进程A对应的程序: #include <iostream> #include <windows.h> using namespace

Windows API 学习指南

1.WindowsAPI开发入门2.Windows数据类型3.Windows数据类型与WindowsAPI函数4.Windows数据结构5.将系统目录信息写入文件6.窗口创建以及消息处理7.使用对话框资源创建窗口8.使用MFC创建对话框窗口9.宽字符10.三种版本11.字符转换12.遍历卷13.驱动器属性14.磁盘容量15.文件操作的四种方法16.文件操作(一)17.文件操作(二)18.目录操作(一)19.目录操作(二)20.目录操作(三)21.文件属性和时间22.内存映射文件23.系统信息(一