我一直直接使用Windows API来创建命名管道服务器,如下所示:
#include <iostream>
#include <windows.h>
int main() {
// Define the name of the named pipe
const wchar_t* pipeName = L"\\\\.\\pipe\\MyNamedPipe";
// Create the named pipe
HANDLE hPipe = CreateNamedPipe(
pipeName, // Pipe name
PIPE_ACCESS_DUPLEX, // Pipe open mode
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, // Pipe mode
PIPE_UNLIMITED_INSTANCES, // Number of instances
512, // Output buffer size
512, // Input buffer size
NMPWAIT_USE_DEFAULT_WAIT, // Timeout for client connection
nullptr // Security attributes
);
if (hPipe == INVALID_HANDLE_VALUE) {
std::cerr << "Error creating named pipe. Error code: " << GetLastError() << std::endl;
return 1;
}
// Wait for a client to connect
if (ConnectNamedPipe(hPipe, nullptr)) {
std::cout << "Client connected. Waiting for data...\n";
// Read data from the client
char buffer[512];
DWORD bytesRead;
if (ReadFile(hPipe, buffer, sizeof(buffer), &bytesRead, nullptr)) {
std::cout << "Received data from client: " << buffer << std::endl;
} else {
std::cerr << "Error reading from pipe. Error code: " << GetLastError() << std::endl;
}
// Disconnect the pipe
DisconnectNamedPipe(hPipe);
} else {
std::cerr << "Error waiting for client connection. Error code: " << GetLastError() << std::endl;
}
// Close the pipe handle
CloseHandle(hPipe);
return 0;
}
Boost.Asio
或类似的现代 C++ 解决方案。我在网上找到的所有代码要么不涵盖这个用例,要么无法编译:
#include <iostream>
#include <boost/asio.hpp>
using namespace boost::asio;
int main() {
io_service ioService;
// Define the name of the named pipe
const char* pipeName = "\\\\.\\pipe\\MyNamedPipe";
// Create a local endpoint
local::stream_protocol::endpoint endpoint(pipeName);
// Create and open the acceptor
local::stream_protocol::acceptor acceptor(ioService, endpoint);
std::cout << "Waiting for client connection...\n";
// Wait for a client to connect
local::stream_protocol::socket socket(ioService);
acceptor.accept(socket);
std::cout << "Client connected. Waiting for data...\n";
// Read data from the client
char buffer[512];
size_t bytesRead = socket.read_some(buffer, ioService); // Error 'boost::asio::basic_stream_socket<boost::asio::local::stream_protocol,boost::asio::any_io_executor>::read_some': no matching overloaded function found
std::cout << "Received data from client: " << std::string(buffer, bytesRead) << std::endl;
// Close the socket (automatically disconnects the client)
socket.close();
return 0;
}
我的 Boost 是通过
vcpkg安装的版本
1.82.0#1
。非常感谢任何帮助 Boost 示例成功编译和运行的帮助。
local::stream_protocol
适用于 UNIX 域套接字。它们是 POSIX 特定的。
相反,您想使用 Windows 面向流的句柄。
之后,
read_some
函数被记录,并具有以下重载:
template<typename MutableBufferSequence>
size_t read_some(const MutableBufferSequence & buffers);
template<typename MutableBufferSequence>
size_t read_some(const MutableBufferSequence & buffers, error_code & ec);
首先,原始字符数组不是缓冲区序列,我完全不清楚为什么要将服务填充到最后一个参数中。
这里已修复:
char buffer[512];
size_t bytesRead = socket.read_some(asio::buffer(buffer));
事实上,我会避免使用 C 风格的原始数组:
std::array<char, 512> buffer;
size_t bytesRead = socket.read_some(asio::buffer(buffer));
松散笔记:
boost::asio
中声明的符号相冲突(也明确允许 ADL)。io_service
,而是使用较新的 io_context