【发布时间】:2018-07-02 09:00:48
【问题描述】:
我需要我的客户端首先检查服务器是否正在从管道读取数据,如果是,则等待服务器完成,否则将数据写入管道。如果我不在示例客户端程序中使用 sleep 命令,则服务器无法正确读取消息。我从它说的文档中找到了这个问题的原因:
此缓冲区必须在读取操作期间保持有效。在读取操作完成之前,调用者不得使用此缓冲区。
但它没有指定在读取操作完成之前如何阻止客户端。
服务器代码:
#include<stdio.h>
#include<windows.h>
#include<iostream>
using namespace std;
int main(void)
{
HANDLE hPipe;
char buffer[1024];
DWORD dwRead;
hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"),
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
1,
1024 * 16,
1024 * 16,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
while (hPipe != INVALID_HANDLE_VALUE)
{
if (ConnectNamedPipe(hPipe, NULL) != FALSE) // wait for someone to connect to the pipe
{
while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE)
{
/* add terminating zero */
buffer[dwRead] = '\0';
/* do something with data in buffer */
printf("%s", buffer);
}
}
DisconnectNamedPipe(hPipe);
}
return 0;
}
客户代码:
#include<stdio.h>
#include<windows.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
void fun()
{
HANDLE hPipe;
DWORD dwWritten;
hPipe = CreateFile(TEXT("\\\\.\\pipe\\Pipe"),
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hPipe != INVALID_HANDLE_VALUE)
{
WriteFile(hPipe,
"Hello Pipe",
11, // = length of string + terminating '\0' !!!
&dwWritten,
NULL);
CloseHandle(hPipe);
}
}
int main(void)
{
int a = 5;
cout<<a;
for(int i = 0; i<a; i++)
{
fun();
Sleep(2000);
}
return (0);
}
这只是一个示例程序,实际上我的客户端是一个非常大的应用程序,它有很多功能,我不想对其进行任何重大更改。每当触发特定功能时,它都应将数据传递给服务器。数据的类型是结构。在服务器中接收数据后,我想将该数据写入文本文件(将其转换为 json 格式后)。
那么如何让我的客户端在将数据写入管道之前检查服务器是否已完成从管道读取数据?客户端不应永远等待服务器,因为它会影响我的客户端应用程序。它应该等待指定的时间间隔。还要传递结构,我应该使用 BYTE MODE 还是 MESSAGE MODE?
【问题讨论】:
-
如何阻止客户端直到读取操作完成 - 因为您使用同步句柄,这将由系统自动完成。 如何检查.. 你不需要检查这个。这根本不可能。您的任务 - 打开文件并向其中写入数据。如果你不想阻塞 - 使用异步句柄
-
如果我不使用 sleep(),我的服务器无法正确读取数据。如果它是自动完成的,那为什么我没有得到正确的输出?
-
因为您的代码中有一些错误。当然不需要任何
Sleep -
您的服务器逻辑也不正确 -
ConnectNamedPipe可以返回 false 并返回错误ERROR_NO_DATA但数据实际存在于管道中。在这种情况下,您也可以致电ReadFile。可以和ERROR_PIPE_CONNECTED调用错误ConnectNamedPipe- 再次 - 这是好的代码,在此之后需要ReadFile -
我是管道概念的新手,你能在答案中写下修改后的客户端和服务器代码吗?
标签: c++ windows ipc named-pipes