【问题标题】:Can we create unnamed socket with boost.asio to emulate anonymous pipe?我们可以用 boost.asio 创建未命名的套接字来模拟匿名管道吗?
【发布时间】:2017-03-18 22:26:56
【问题描述】:
socketpair() 在 Linux 上允许您创建未命名的套接字。 boost.asio 库中有类似的东西吗?我正在尝试使用 boost.asio 库来模拟匿名管道。我知道 boost.process 支持这一点,但我想使用 boost.asio 库。顺便问一下,为什么 boost.asio 中缺少匿名管道?
【问题讨论】:
标签:
c++
boost
ipc
boost-asio
【解决方案1】:
我编写了下面的代码来使用 boost.asio 库来模拟管道。它只有演示代码,没有消息边界检查、错误检查等。
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
#include <cctype>
#include <boost/array.hpp>
using boost::asio::local::stream_protocol;
int main()
{
try
{
boost::asio::io_service io_service;
stream_protocol::socket parentSocket(io_service);
stream_protocol::socket childSocket(io_service);
//create socket pair
boost::asio::local::connect_pair(childSocket, parentSocket);
std::string request("Dad I am your child, hello!");
std::string dadRequest("Hello son!");
//Create child process
pid_t pid = fork();
if( pid < 0 ){
std::cerr << "fork() erred\n";
} else if (pid == 0 ) { //child process
parentSocket.close(); // no need of parents socket handle, childSocket is bidirectional stream socket unlike pipe that has different handles for read and write
boost::asio::write(childSocket, boost::asio::buffer(request)); //Send data to the parent
std::vector<char> dadResponse(dadRequest.size(),0);
boost::asio::read(childSocket, boost::asio::buffer(dadResponse)); //Wait for parents response
std::cout << "Dads response: ";
std::cout.write(&dadResponse[0], dadResponse.size());
std::cout << std::endl;
} else { //parent
childSocket.close(); //Close childSocket here use one bidirectional socket
std::vector<char> reply(request.size());
boost::asio::read(parentSocket, boost::asio::buffer(reply)); //Wait for child process to send message
std::cout << "Child message: ";
std::cout.write(&reply[0], request.size());
std::cout << std::endl;
sleep(5); //Add 5 seconds delay before sending response to parent
boost::asio::write(parentSocket, boost::asio::buffer(dadRequest)); //Send child process response
}
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
std::exit(1);
}
}