C++ 使用 Windows 命名管道
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1236460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Using windows named pipes
提问by Fire Lancer
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?
在 ConnectNamedPipe 之后,master 永远不会退出 WaitForSingleObject,而 slave 在第一个 boost::asio::read 调用中抛出异常,“等待进程打开管道的另一端”,我认为 WaitNamedPipe 是为了等待与主中的 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
奴隶.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.
显然我完全错了,但是我在网上找不到任何东西来比较我的代码。
回答by sylvanaar
In your slave you need to call CreateFile() to open the pipe, not CreateNamedPipe.
在您的从属设备中,您需要调用 CreateFile() 来打开管道,而不是 CreateNamedPipe。
HANDLE pipe = CreateFile("\\.\pipe\FLTest",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
回答by steve
You need to specify the mode of the pipe in the server part as PIPE_WAIT
您需要在服务器部分指定管道的模式为 PIPE_WAIT