我正在尝试实现基本的命名管道实现。
在我的客户端代码中,如果我仅调用fun()
一次,则我的程序将完全正常运行。
但是当我多次致电fun()
时,它会交替失败(例如,如果我致电fun()
3次,则第一次呼叫将成功,第二次呼叫将失败,而第三次呼叫可以正常运行。
当GetLastError()
中的呼叫失败时,屏幕上将显示231
作为输出。
如果我在客户端中的每个Sleep()
调用之后都使用fun()
,则我的程序对于每个fun()
的调用都可以正常运行。
如果我在服务器程序中使用Sleep()
,那么它将仅从缓冲区读取一次,并且所有对fun()
的调用(在第一次调用之后)都在客户端失败。
服务器代码:
#include<stdio.h>
#include<windows.h>
#include<iostream>
#include<stdlib.h>
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, // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
1,
1024 * 16,
1024 * 16,
INFINITE,
NULL);
while (hPipe != INVALID_HANDLE_VALUE)
{
switch (ConnectNamedPipe(hPipe, NULL) ? NOERROR : GetLastError())
{
case NOERROR:
case ERROR_PIPE_CONNECTED: // STATUS_PIPE_CONNECTED
case ERROR_NO_DATA: // STATUS_PIPE_CLOSING
while (ReadFile(hPipe, buffer, sizeof(buffer)-1, &dwRead, NULL))
{
// do something with data in buffer
//Sleep(2000);
buffer[dwRead] = '\0';
printf("%s", buffer);
}
DisconnectNamedPipe(hPipe);
break;
}
//CloseHandle(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\n",
12, // = length of string + '\0'
&dwWritten,
NULL);
CloseHandle(hPipe);
}
else
{
cout<<"****";
cout<<GetLastError();
cout<<"****";
}
}
int main(void)
{
fun(); //Success
//Sleep(2000);
fun(); //failure
//Sleep(2000);
fun(); //Success
//Sleep(2000);
fun(); //failure
//Sleep(2000);
fun(); //Success
return (0);
}