C++ 使用 Windows 命名管道
由于某种原因,桅杆和从属装置都失败了,但是我可以找到任何关于它们如何工作的好例子,所以我不确定我哪里出了问题。
在 ConnectNamedPipe 之后,主设备永远不会退出 WaitForSingleObject,并且从设备在第一个 boost::asio::read 调用中抛出异常,“等待进程打开管道的另一端”,我认为 WaitNamedPipe 的目的是与master中的ConnectNamedPipe一起等待吗?
master.cpp
asio::io_service ioservice;
asio::windows::stream_handle in(ioservice);
int main()
{
HANDLE pipe = INVALID_HANDLE_VALUE;
try
{
//create pipe
pipe = CreateNamedPipe("\\\\.\\pipe\\FLTest",
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
255, 50000,50000, 0, 0);
if(pipe == INVALID_HANDLE_VALUE)
{
printWinError();
return -1;
}
in.assign(pipe);
std::cout << "Created pipe" << std::endl;
//spawn child
STARTUPINFO startInfo;
ZeroMemory(&startInfo, sizeof(STARTUPINFO));
startInfo.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION procInfo;
ZeroMemory(&procInfo, sizeof(PROCESS_INFORMATION));
if(CreateProcess(0, "slave.exe", 0,0, FALSE, CREATE_NEW_CONSOLE,
0, 0, &startInfo, &procInfo))
{
std::cout << "Slave process created" << std::endl;
}
else
{
printWinError();
DisconnectNamedPipe(pipe);
return -1;
}
OVERLAPPED overlapped = {0};
overlapped.hEvent = CreateEvent(0,TRUE,FALSE,0);
if(ConnectNamedPipe(pipe, &overlapped) == FALSE)
{
unsigned error = GetLastError();
if(error != ERROR_PIPE_CONNECTED &&
error != ERROR_IO_PENDING)
{
printWinError();
DisconnectNamedPipe(pipe);
return -1;
}
}
WaitForSingleObject(overlapped.hEvent, INFINITE);
CloseHandle(overlapped.hEvent);
std::cout << "Pipe connected" << std::endl;
for(int i = 0; i < 100; ++i)
{
boost::system::error_code error;
unsigned n = i * 5;
asio::write(in,asio::buffer((char*)&n, sizeof(unsigned)),
asio::transfer_all(), error);
if(error)throw boost::system::system_error(error);
}
std::cout << "Sent data" << std::endl;
FlushFileBuffers(pipe);
DisconnectNamedPipe(pipe);
system("pause");
return 0;
}
catch(const std::exception &e)
{
std::cout << e.what() << std::endl;
if(pipe != INVALID_HANDLE_VALUE)
DisconnectNamedPipe(pipe);
system("pause");
return -1;
}
}
Slave.cpp
asio::io_service ioservice;
asio::windows::stream_handle in(ioservice);
int main()
{
try
{
WaitNamedPipe("\\\\.\\pipe\\FLTest", NMPWAIT_WAIT_FOREVER);
std::cout << "Pipe avaible" << std::endl;
HANDLE pipe = CreateNamedPipe("\\\\.\\pipe\\FLTest",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
255, 50000,50000,0,0);
if(pipe == INVALID_HANDLE_VALUE)
{
printWinError();
return -1;
}
in.assign(pipe);
std::cout << "Pipe connected" << std::endl;
for(int i = 0; i < 100; ++i)
{
std::cout << "i: " << i << std::endl;
boost::system::error_code error;
unsigned n;
asio::read(in,asio::buffer((char*)&n,sizeof(unsigned)),
asio::transfer_all(), error);
if(error)throw boost::system::system_error(error);
}
system("pause");
return 0;
}
catch(const std::exception &e)
{
std::cout << e.what() << std::endl;
system("pause");
return -1;
}
}
显然我得到了完全错误的东西,但是我在网上找不到任何东西可以与我的代码进行比较。
For some reason both the mast and slave fail, however I could find any good examples on how their meant to work, so im not sure where I went wrong.
The master never exits the WaitForSingleObject after ConnectNamedPipe, and the slave throws an exception in the first boost::asio::read call, "Waiting for a process to open the other end of the pipe", which I though the WaitNamedPipe was meant to wait for along with the ConnectNamedPipe in the master?
master.cpp
asio::io_service ioservice;
asio::windows::stream_handle in(ioservice);
int main()
{
HANDLE pipe = INVALID_HANDLE_VALUE;
try
{
//create pipe
pipe = CreateNamedPipe("\\\\.\\pipe\\FLTest",
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
255, 50000,50000, 0, 0);
if(pipe == INVALID_HANDLE_VALUE)
{
printWinError();
return -1;
}
in.assign(pipe);
std::cout << "Created pipe" << std::endl;
//spawn child
STARTUPINFO startInfo;
ZeroMemory(&startInfo, sizeof(STARTUPINFO));
startInfo.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION procInfo;
ZeroMemory(&procInfo, sizeof(PROCESS_INFORMATION));
if(CreateProcess(0, "slave.exe", 0,0, FALSE, CREATE_NEW_CONSOLE,
0, 0, &startInfo, &procInfo))
{
std::cout << "Slave process created" << std::endl;
}
else
{
printWinError();
DisconnectNamedPipe(pipe);
return -1;
}
OVERLAPPED overlapped = {0};
overlapped.hEvent = CreateEvent(0,TRUE,FALSE,0);
if(ConnectNamedPipe(pipe, &overlapped) == FALSE)
{
unsigned error = GetLastError();
if(error != ERROR_PIPE_CONNECTED &&
error != ERROR_IO_PENDING)
{
printWinError();
DisconnectNamedPipe(pipe);
return -1;
}
}
WaitForSingleObject(overlapped.hEvent, INFINITE);
CloseHandle(overlapped.hEvent);
std::cout << "Pipe connected" << std::endl;
for(int i = 0; i < 100; ++i)
{
boost::system::error_code error;
unsigned n = i * 5;
asio::write(in,asio::buffer((char*)&n, sizeof(unsigned)),
asio::transfer_all(), error);
if(error)throw boost::system::system_error(error);
}
std::cout << "Sent data" << std::endl;
FlushFileBuffers(pipe);
DisconnectNamedPipe(pipe);
system("pause");
return 0;
}
catch(const std::exception &e)
{
std::cout << e.what() << std::endl;
if(pipe != INVALID_HANDLE_VALUE)
DisconnectNamedPipe(pipe);
system("pause");
return -1;
}
}
slave.cpp
asio::io_service ioservice;
asio::windows::stream_handle in(ioservice);
int main()
{
try
{
WaitNamedPipe("\\\\.\\pipe\\FLTest", NMPWAIT_WAIT_FOREVER);
std::cout << "Pipe avaible" << std::endl;
HANDLE pipe = CreateNamedPipe("\\\\.\\pipe\\FLTest",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
255, 50000,50000,0,0);
if(pipe == INVALID_HANDLE_VALUE)
{
printWinError();
return -1;
}
in.assign(pipe);
std::cout << "Pipe connected" << std::endl;
for(int i = 0; i < 100; ++i)
{
std::cout << "i: " << i << std::endl;
boost::system::error_code error;
unsigned n;
asio::read(in,asio::buffer((char*)&n,sizeof(unsigned)),
asio::transfer_all(), error);
if(error)throw boost::system::system_error(error);
}
system("pause");
return 0;
}
catch(const std::exception &e)
{
std::cout << e.what() << std::endl;
system("pause");
return -1;
}
}
Obviously ive got something completely wrong, however I couldn't find anything on the net to compare my code with.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的从站中,您需要调用 CreateFile() 来打开管道,而不是 CreateNamedPipe。
In your slave you need to call CreateFile() to open the pipe, not CreateNamedPipe.
您需要在服务器部分指定管道的模式为 PIPE_WAIT
You need to specify the mode of the pipe in the server part as PIPE_WAIT