管道通讯 C++
我正在编写两个必须通信的小型 C++ 应用程序。第一个是一项服务,每隔一段时间就必须提醒用户一些事情。由于服务无法创建窗口,因此我将应用程序设计为两个单独的可执行文件。
该服务将使用通知程序进行通信。
该服务只需向通知程序发送短信,通知程序就会在系统托盘中显示一个气球。
我正在尝试使用命名管道,我想我已经差不多完成了,但还没有完全完成。到目前为止我所拥有的是:
在通知方:
m_hInPipe = CreateNamedPipe(L"\\\\.\\pipe\\nhsupspipe", PIPE_ACCESS_INBOUND,
PIPE_WAIT, 1, 1024, 1024, 60, NULL);
这意味着我创建了一个名为 nhsupspipe 的管道,一个入站管道。
在服务端:
if (!WriteFile(m_hOutPipe, "My message to the user?", 23, &escritos, &o))
std::cout << "ERROR: " << GetLastError();
调试我可以看到一切正常,管道已创建,并且 WriteFile 将我的 23 个字节写入管道。
我的问题是:在通知方,我如何能够读取这些字节?是否有任何消息发送到进程?我必须为管道编写处理程序吗?任何事物?
I´m writing two litle c++ apps that must communicate. First one will be a service which, every once in a while, must alert the user for something. Since a service cannot create windows I designed the app to be two separate executables.
The service will use a notifier to communicate.
The service needs only to send text messages to the notifier wich will show up a balloon at system tray.
I´m trying to use named pipes and I think I´m almost there, but not quite there. What I have so far is:
At the notifier side:
m_hInPipe = CreateNamedPipe(L"\\\\.\\pipe\\nhsupspipe", PIPE_ACCESS_INBOUND,
PIPE_WAIT, 1, 1024, 1024, 60, NULL);
Meaning I created a pipe named nhsupspipe, an inbound pipe.
At the service side:
if (!WriteFile(m_hOutPipe, "My message to the user?", 23, &escritos, &o))
std::cout << "ERROR: " << GetLastError();
Debugging I can see that it is all ok, the pipe is created and the WriteFile writes my 23 bytes to the pipe.
My question is: How, in the notifier side I´ll be able to read these bytes? Is there any message sent to the process? Do I have to write a handler for the pipe? Anything?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
来自客户(您的服务)和的一些简单片段服务器(通知者)
[注意:这是改编自我不久前完成的一个项目,该项目又受到 CreateNamedPipe 和 CreateNamedPipe 的 MSDN 示例的严重“影响”。 co]:
服务器端:
客户端:
上面提到的消息是一个将成为您的消息的结构,您可能需要包。
因为在您的场景中,客户端(服务)可能会启动并启动。在服务器(通知程序)之前运行,您需要在客户端制定某种重新连接策略。
稍微不同的一点是,您应该仔细考虑奥斯特曼先生在他的回复中所说的话(甚至不为别的,只因为他是拉里·奥斯特曼)。
Some simple snippets from the client (your service) & the server (the notifier)
[Note: This is adapted from a project I've done a while ago which in turn was heavily "influenced" by the MSDN samples from CreateNamedPipe & co]:
Server side:
The client:
The Message mentioned above is a structure that will be your message, which you will probably want to pack.
Since in your scenario the client (the service) will probably be up & running before the server (the notifier) you'll need to have in place some kind of reconnection strategy on the client side.
And on a slightly different note you should consider carefully what Mr. Osterman said in his reply (even for nothing else but because he's Larry Osterman).
您需要使用 ReadFile 或 ReadFileEx(用于重叠 I/O)通常位于通知方在线程或消息循环中。另请参阅 CreateNamedPipe 和 < a href="http://msdn.microsoft.com/en-us/library/aa365800(VS.85).aspx" rel="nofollow noreferrer">等待NamedPipe。
You need to use ReadFile or ReadFileEx (for Overlapped I/O) on notifier side typically in a thread or message loop. Also look at the documentation for CreateNamedPipe and WaitNamedPipe.
在这种情况下,我可能会使用 RPC 而不是原始命名管道。使用原始命名管道,您必须解析来自客户端的数据,这可能会出现安全错误。使用 RPC,您可以让 RPC 为您解析数据,这减少了引入错误的机会。
In this circumstance, I'd probably use RPC instead of raw named pipes. With raw named pipes, you have to parse the data from the client which introduces the possibility of security bugs. With RPC you can let RPC parse the data for you which decreases the chance of introducing an error.
不完全是问题,但另一个选择是 CreateEvent() 和内存映射文件。
Not exactly the question, but another option is CreateEvent() and a memory mapped file.
如果我这样做,我会让服务端执行 CreateNamedPipe(出站),然后调用 ConnectNamedPipe 等待通知程序连接。
在通知程序方面,我将
CreateFile
与FILE_FLAG_OVERLAPPED
一起使用。这样,当数据可供读取时,管道的句柄将收到信号。您的通知程序(大概)还将维护一个 GUI,因此您可能希望让它在其事件循环中调用MsgWaitForMultipleObjects
。这将等待消息被处理或等待管道上传入的数据被处理。这几乎像普通的事件循环一样工作,只是它的返回值与GetMessage()
略有不同 - 如果您的句柄收到信号,它将返回WAIT_OBJECT_0
,或者WAIT_OBJECT_0 + 1
如果您有一条消息(假设您只让它在一个句柄上等待 - 它实际上是WAIT_OBJECT_0 + N
,其中N
是您让它等待的句柄数)。在大多数情况下,它就像一个普通的PeekMessage
或GetMessage
循环 - 等待,直到有事情要做,做,再等待。If I were doing this, I'd have the service side do the
CreateNamedPipe
(outbound), and then callConnectNamedPipe
to wait for the notifier to connect.On the notifier side, I'd use
CreateFile
withFILE_FLAG_OVERLAPPED
. With that, the handle to the pipe will be signaled when data becomes available to read. Your notifier will (presumably) also be maintaining a GUI, so you'll probably want to have it callMsgWaitForMultipleObjects
in its event loop. That will wait for messages to be processed or data coming in on the pipe to be processed. That will work almost like a normal event loop, except that its return value is slightly different fromGetMessage()
-- it'll returnWAIT_OBJECT_0
if your handle is signaled, orWAIT_OBJECT_0 + 1
if you have a message (assuming you only have it wait on the one handle -- it's reallyWAIT_OBJECT_0 + N
, whereN
is the number of handles you had it wait on). For the most part, it's like a normalPeekMessage
orGetMessage
loop -- wait 'til there's something to do, do it, wait again.