我有一个协议结构,其中一个类负责协议状态(Protocol
),另一个类负责发送和接收消息(Comm
)。
我在异步模式下使用boost:asio
。
所以我有以下代码结构:
#include <string>
#include <iostream>
#include "boost/asio.hpp"
#include "boost/bind.hpp"
class Comm {
public:
Comm::Comm();
void SendMessage(std::string message, void (callback) (const boost::system::error_code& errorCode, std::size_t bytesTranferred));
private:
boost::asio::io_service ioService;
std::shared_ptr<boost::asio::ip::tcp::socket> mySocket;
};
Comm::Comm()
{
boost::asio::ip::tcp::resolver resolver(ioService);
boost::asio::ip::tcp::resolver::query query("192.168.0.1");
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
mySocket->connect(*iterator);
}
void Comm::SendMessage(std::string message, void (callback) (const boost::system::error_code& errorCode, std::size_t bytesTranferred))
{
mySocket->async_send(boost::asio::buffer(message.c_str(), message.length()), boost::bind(&callback)); // <<< ERROR HERE
}
class Protocol {
public:
void SendMessage(std::string message);
void SendMessageHandler(const boost::system::error_code& errorCode, std::size_t bytesTranferred);
private:
Comm channel;
};
void Protocol::SendMessage(std::string message)
{
channel.SendMessage(message, &SendMessageHandler); // <<< ERROR HERE
}
void Protocol::SendMessageHandler(const boost::system::error_code& errorCode, std::size_t bytesTranferred)
{
if (!errorCode)
std::cout << "Send OK" << std::endl;
else
std::cout << "Send FAIL." << std::endl;
}
如图所示,我需要将async_send
的回调作为调用者类的非静态函数,因此我必须在SendMessage
中传递回调函数并将其用作async_send
中的参数。
这两个陈述都没有编译。我尝试了变化,但我找不到发生了什么。
帮助表示赞赏。
答案 0 :(得分:1)
使用binding to class method尝试这样的事情:
void Comm::SendMessage(std::string message, boost::function< void(const boost::system::error_code& , std::size_t) > callback )
{
mySocket->async_send(boost::asio::buffer(message.c_str(), message.length()), callback);
}
...//later
channel.SendMessage(message, boost::bind(&Protocol::SendMessageHandler, this) );
注意/更重要的是,这里有大量无法修复的错误:
std::string message
多次 - 它会复制内容。Comm::SendMessage
使用本地message
对象,在异步操作完成之前将被销毁(boost::asio::buffer
不会复制内容)。Comm
个对象,因为每个对象都有自己的ioService
(您无法同时运行它们)SendMessageHandler
已被销毁后,您可以调用Protocol
。Protocol
无法控制写并行性,多个SendMessage
调用可能导致将混合缓冲区写入套接字,这可以/将通过网络发送完整的垃圾。考虑将asio examples中的一个作为基本使用模式。