C++ 命名管道问题
我试图学习命名管道是如何工作的,并创建了两个控制台来测试服务器和客户端之间的连接。客户端将向服务器发送一条消息,服务器将显示该消息,但它返回的不是该消息,而是“nullptr”值,如VS的错误异常中断中所示 下面是我的代码,如果你发现我的代码有任何问题,请告诉我,我仍在学习 Server.cppC++ 命名管道问题,c++,winapi,named-pipes,C++,Winapi,Named Pipes,我试图学习命名管道是如何工作的,并创建了两个控制台来测试服务器和客户端之间的连接。客户端将向服务器发送一条消息,服务器将显示该消息,但它返回的不是该消息,而是“nullptr”值,如VS的错误异常中断中所示 下面是我的代码,如果你发现我的代码有任何问题,请告诉我,我仍在学习 Server.cpp #include "cust_ostream.hpp" #include <Windows.h> #include <iostream> #include <conio.h
#include "cust_ostream.hpp"
#include <Windows.h>
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
LPVOID buffer = NULL;
DWORD readbyte;
cout << "---Named Pipe Server Test---" << endl << endl;
cout << "Creating named pipe: \\\\.\\pipe\\mypipe" << endl;
HANDLE hPipe = CreateNamedPipeA("\\\\.\\pipe\\mypipe", PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, NULL);
if (!hPipe || hPipe == INVALID_HANDLE_VALUE)
{
cout << "Pipe creation failed." << endl;
return 0;
}
cout << "Connecting pipe to client..." << endl;
BOOL connect = ConnectNamedPipe(hPipe, NULL);
if (!connect)
{
cout << "Connect named pipe failed" << endl;
}
cout << "Success! Reading pipe message from client..." << endl;
ReadFile(hPipe, buffer, sizeof(buffer), &readbyte, NULL);
c_cout << "Pipe message = " << *(int *)buffer << endl;
_getch();
return 0;
}
#包括“cust_ostream.hpp”
#包括
#包括
#包括
使用名称空间std;
int main()
{
LPVOID buffer=NULL;
双字读字节;
cout您需要等待NamedPipe上有ConnectPipeReady事件。目前,您正在尝试创建管道,但实际上没有看到它是否成功。请参阅此处有关命名管道的MSDN文档:
具体而言,该区块:
while (1)
{
hPipe = CreateFile(
lpszPipename, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
// Break if the pipe handle is valid.
if (hPipe != INVALID_HANDLE_VALUE)
break;
// Exit if an error other than ERROR_PIPE_BUSY occurs.
if (GetLastError() != ERROR_PIPE_BUSY)
{
_tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() );
return -1;
}
// All pipe instances are busy, so wait for 20 seconds.
if ( ! WaitNamedPipe(lpszPipename, 20000))
{
printf("Could not open pipe: 20 second wait timed out.");
return -1;
}
}
另外,您不应该使用#define endl“\n”
,使用std::endl
您已经将缓冲区初始化为NULL,这意味着默认情况下其长度为零。现在,当您在服务器的read函数中使用sizeof运算符时(用于检索服务器从客户端接收的消息),发生的情况是,您要求Read函数中的sizeof运算符读取0字节!这意味着不会读取任何内容
为了解决这个问题,您可以声明一个大小为100的字符数组,或者声明一个您确信客户端不会超过的消息大小。例如,如果您假设客户端的消息长度不会超过60个字符,那么您可以创建大小为100的字符缓冲区,以确保能够容纳所有消息e由客户提供
还有一件事,如果问题仍然存在,请不要在读取中使用sizeof,而是使用100或字符缓冲区数组的任何大小。这应该可以解决您的问题。缓冲区
为空。您从未为其分配过任何内容,因此nullptr
异常正是您所期望的。分配一些内存并将其分配给Buffer
或只是使用预先分配的数组。天哪,我错过了!感谢您指出@CareyGregory。nullptr
异常将保留,因为他试图读取空指针。@Tanner,是的,我创建它只是为了看看它是如何工作的,实际上这些错误检查已经实现了。感谢您指出这是我的想法
#include <Windows.h>
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
LPVOID data;
DWORD writebyte;
int i = 2;
cout << "---Named Pipe Client---" << endl << endl;
cout << "Creating pipe file: \\\\.\\pipe\\mypipe" << endl;
HANDLE pipe = CreateFileA("\\\\.\\pipe\\mypipe", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (!pipe || pipe == INVALID_HANDLE_VALUE)
{
cout << "Pipe client failed." << endl;
return 0;
}
cout << "Pipe connected to server, sending data..." << endl;
WriteFile(pipe, &i, sizeof(i), &writebyte, NULL);
_getch();
return 0;
}
while (1)
{
hPipe = CreateFile(
lpszPipename, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
// Break if the pipe handle is valid.
if (hPipe != INVALID_HANDLE_VALUE)
break;
// Exit if an error other than ERROR_PIPE_BUSY occurs.
if (GetLastError() != ERROR_PIPE_BUSY)
{
_tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() );
return -1;
}
// All pipe instances are busy, so wait for 20 seconds.
if ( ! WaitNamedPipe(lpszPipename, 20000))
{
printf("Could not open pipe: 20 second wait timed out.");
return -1;
}
}