【发布时间】:2016-05-04 22:57:29
【问题描述】:
我正在为 IRC 机器人使用 boost asio,而我的一个异步操作导致文件描述符错误。我试图将套接字放在 shared_ptr 中,但仍然出现“错误文件描述符”错误。我不知道它有什么问题。
这是文件,我省略了cpp文件中的一些功能。但是我想阅读完整的文件,在我的 Github 上是 here。
错误发生在_read函数中。
谢谢!
irc.hpp
#ifndef H_IRC
#define H_IRC
#include <vector>
#include <boost/asio.hpp>
#include <boost/tokenizer.hpp>
#include <boost/shared_ptr.hpp>
class Irc
{
public:
Irc(const std::string &server, const std::string &port, const std::function<void()> onConnect);
void connect();
void close();
void user(const std::string &username);
void user(const std::string &username, const std::string &hostname, const std::string &server, const std::string &realname);
void nick(std::string &nickname);
void join(const std::string &chan);
void part(const std::string &chan);
void privmsg(const std::string &to, const std::string &msg);
void command(const std::string &cmd, const std::string &msg);
void command(const std::string &cmd, const std::string &to, const std::string &msg);
void run();
private:
void _read(const boost::system::error_code &error);
void _send(std::string &message);
void _readHandler(const boost::tokenizer<boost::char_separator<char> > &tokenizer);
void _connectHandler(const boost::system::error_code &error);
void _pong(const std::string &ping);
std::string _server;
std::string _port;
std::string _chan;
std::vector<std::function<void (const boost::tokenizer<boost::char_separator<char> >&)>> _readHandlers;
std::function<void()> _onConnect;
boost::asio::streambuf _buffer;
boost::asio::io_service _ios;
boost::shared_ptr<boost::asio::ip::tcp::socket> _socket;
};
#endif
irc.cpp
#include "irc.hpp"
#include <iostream>
#include <boost/bind.hpp>
#include <boost/make_shared.hpp>
Irc::Irc(const std::string &server, const std::string &port, const std::function<void()> onConnect)
: _server(server), _port(port), _onConnect(onConnect),
_socket(boost::make_shared<boost::asio::ip::tcp::socket>(boost::ref(_ios)))
{
// Ping back handler
_readHandlers.push_back([this](const boost::tokenizer<boost::char_separator<char> > &tokenizer) {
std::vector<std::string> tokens(begin(tokenizer), end(tokenizer));
if(tokens[0].compare("PING") == 0)
_pong(tokens[1]);
});
}
void Irc::connect()
{
boost::asio::ip::tcp::resolver resolver(_ios);
boost::asio::ip::tcp::resolver::query query(_server, _port);
boost::asio::ip::tcp::resolver::iterator it = resolver.resolve(query);
boost::asio::ip::tcp::resolver::iterator end;
boost::system::error_code error = boost::asio::error::host_not_found;
while(it != end)
{
if(!error)
break;
std::cout << "Connecting to " << _server << " " << _port << std::endl;
boost::asio::async_connect(*_socket, it,
boost::bind(&Irc::_connectHandler, this, error)
);
it++;
if(error)
std::cout << "Error : " << error.message() << std::endl;
}
if(error)
std::cout << "Error connectinf to " << _server << " " << error.message() << std::endl;
else
std::cout << "Connection success" << std::endl;
}
void Irc::close()
{
_socket->close();
_ios.stop();
}
void Irc::run()
{
boost::asio::async_read_until(*_socket, _buffer, "\r\n",
boost::bind(&Irc::_read, this,
boost::asio::placeholders::error
)
);
_ios.run();
}
/*
* Private
*/
void Irc::_read(const boost::system::error_code &error)
{
if(error)
{
std::cerr << "Error in read : " << error.message() << std::endl;
}
else
{
std::string data(buffers_begin(_buffer.data()), buffers_begin(_buffer.data()) + _buffer.size());
std::cout << data << std::endl;
boost::char_separator<char> sep("!@:; ");
boost::tokenizer<boost::char_separator<char> > tokenizer(data, sep);
_readHandler(tokenizer);
boost::asio::async_read_until(*_socket, _buffer, "\r\n",
boost::bind(&Irc::_read, this,
boost::asio::placeholders::error
)
);
}
}
inline void Irc::_send(std::string &message)
{
boost::asio::write(*_socket, boost::asio::buffer(message + "\r\n"));
}
void Irc::_readHandler(const boost::tokenizer<boost::char_separator<char> > &tokenizer)
{
for(auto it : _readHandlers)
it(tokenizer);
}
void Irc::_connectHandler(const boost::system::error_code &error)
{
if(!error)
{
_onConnect();
}
}
【问题讨论】:
-
@sehe : 很好,我会把它放在我的书签里,不幸的是我的笔记本电脑上没有 Flashplayer。
-
应该已经支持 HTML5 (lemme check)。 roadmap.livecoding.tv 表示 2016 年第 4 周
-
i.imgur.com/xpk55U1.png 可能是我没有打开的选项?
标签: c++ boost boost-asio