我创建了一个使用boost asio的套接字应用程序,当我尝试从套接字中读取任何内容时,它似乎占用了大量的cpu。
Atm我使用了一个包装类,所以我不必在我的头文件中公开boost头文件,看起来像这样:
class SocketHandle
{
public:
SocketHandle()
{
m_pSocket = NULL;
m_pService = NULL;
}
~SocketHandle()
{
delete m_pSocket;
delete m_pService;
}
void connect(const char* host, const char* port)
{
if (m_pSocket || m_pService)
return;
m_pService = new boost::asio::io_service();
tcp::resolver resolver(*m_pService);
tcp::resolver::query query(tcp::v4(), host, port);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
m_pSocket = new tcp::socket(*m_pService);
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
(*m_pSocket).close();
(*m_pSocket).connect(*endpoint_iterator++, error);
}
if (error)
throw ...
}
tcp::socket* operator->()
{
return m_pSocket;
}
private:
tcp::socket *m_pSocket;
boost::asio::io_service *m_pService;
};
然后即时阅读套接字:
size_t recv(char *data, size_t size)
{
boost::system::error_code error;
size_t len = (*m_pSocket)->read_some(boost::asio::buffer(data, size), error);
if (error)
throw ...
return len;
}
我做错了吗?有没有更好的方法从套接字读取数据?
提升1.39.0 visual c ++ 窗
答案 0 :(得分:1)
您可能希望考虑的更改(我强烈建议)是使您的套接字调用异步。这样你就不必担心线程被阻塞或任何套接字调用内部旋转(我怀疑这可能是你所看到的)。相反,您只需提供一个回调,它将接收任何错误和接收的字节数。
Boost文档中有很多examples说明了如何做到这一点,我发现它可以更有效地利用线程和处理器资源。
答案 1 :(得分:0)
你应该避免紧张的循环:
// BAD.
while (error && endpoint_iterator != end)
{
(*m_pSocket).close();
(*m_pSocket).connect(*endpoint_iterator++, error);
}
而是尝试类似:
try
{
(*m_pSocket).connect(*endpoint_iterator++, error);
// ...
}
catch (std::exception& ex)
{
// Release resources, then try connecting again.
}
另请参阅这些examples以了解使用Asio的正确习语。
答案 2 :(得分:0)
考虑使用免费功能,
size_t len = asio::read(*m_pSocket,asio::buffer(data, size), error);