我正在尝试编写一个命名管道读取器,以使用来自另一个提供命名管道流的应用程序中的事件。我遇到了一个问题,即当命名管道服务器非常快速地一起发送大量事件时,我没有收到来自命名管道服务器的所有事件。
为简化此问题并将其与服务器应用程序正在执行的其他活动隔离开,我决定将其裁剪并编写一个简单的c ++控制台应用程序,该应用程序将写入命名管道,并使我的代码侦听该管道。
创建测试应用程序后,发送批 10 消息,每批之间等待三秒钟。服务器指示每次写操作都成功,但是最后,我的命名管道读取器始终只收到两条消息。
我尝试添加使用Sleep()进行读取操作之间的延迟,但这没有任何效果。但是,当我尝试在服务器上使用Sleep()添加写入操作之间的延迟时,它使我可以在客户端中接收消息。
每批10个,通常1ms Sleep()将允许我获取所有消息。如果我发送更大的批次,则必须稍微增加Sleep()。
我也尝试使用一个简单的C#应用程序进行读取,但这并没有提高我读取所有事件的能力,而没有写操作之间的延迟。
这对我来说非常混乱,因为据我了解,管道应该用作FIFO,所以我不知道这些消息的去向。
有人对这些写作为什么成功有一些见解,但我无法在读者中找到所有这些著作吗?还是为什么在两次写入之间增加一个小的延迟就可以让我阅读它们呢?
我在下面包括了作者和读者代码。我删除了错误处理/验证代码以简化其可读性。对于服务器端,我从尝试使用的生产应用程序中获得了管道定义,因此确保创建的内容相同。
作家
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
using namespace std;
#define BUFFER_SIZE 65535
int main()
{
HANDLE namedPipeHandle;
BOOL fSuccess = FALSE;
DWORD bytesRead;
wstring pipeName = L"\\\\.\\pipe\\TestPipe";
namedPipeHandle = CreateNamedPipe(pipeName.c_str(),
PIPE_ACCESS_DUPLEX |FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
BUFFER_SIZE,
BUFFER_SIZE,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
bool isConnected = ConnectNamedPipe(namedPipeHandle, NULL);
DWORD bytesWritten = 0;
string message = "TEST";
int count = 0;
while (true)
{
for (int i = 0; i < 10; i++)
{
fSuccess = WriteFile(namedPipeHandle, message.c_str(), message.size(), &bytesWritten, NULL);
if (fSuccess)
{
count++;
}
//Sleep(1); // Adding the Sleep(1) allows me to receive each batch of 10 in the client.
}
cout << "Sent " << count << " total messages" << endl;
Sleep(3000);
}
}
阅读器
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
using namespace std;
#define BUFFER_SIZE 65535
int main()
{
HANDLE hPipe;
char buffer[BUFFER_SIZE];
DWORD bytesRead;
wstring pipeName = L"\\\\.\\pipe\\TestPipe";
hPipe = CreateFile(pipeName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
int receivedCount = 0;
int failedCount = 0;
do
{
bool fSuccess;
fSuccess = ReadFile(hPipe, buffer, BUFFER_SIZE, &bytesRead, NULL);
if (fSuccess)
{
receivedCount++;
}
else
{
failedCount++;
}
cout << "Total Events Received: " << receivedCount << endl;
cout << "Total Events Failed: " << failedCount << endl;
} while (true);
CloseHandle(hPipe);
return 0;
}