C++ 使用命名管道
Posted
技术标签:
【中文标题】C++ 使用命名管道【英文标题】:C++ Using windows named pipes 【发布时间】:2009-08-06 00:48:23 【问题描述】:由于某种原因,桅杆和从站都失败了,但是我可以找到任何关于它们如何工作的好例子,所以我不确定我哪里出错了。
主机在 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;
很明显我搞错了,但是我在网上找不到任何东西可以用来比较我的代码。
【问题讨论】:
【参考方案1】:在您的从属服务器中,您需要调用 CreateFile() 来打开管道,而不是 CreateNamedPipe。
HANDLE pipe = CreateFile("\\\\.\\pipe\\FLTest",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
【讨论】:
【参考方案2】:需要在服务器部分指定管道的模式为PIPE_WAIT
【讨论】:
以上是关于C++ 使用命名管道的主要内容,如果未能解决你的问题,请参考以下文章