Boost::asio::acceptor在win7上挂起

boost::asio::acceptor hangs up on win7

本文关键字:挂起 win7 acceptor asio Boost      更新时间:2023-10-16

我已经实现了一个简单的启动tcp连接的boost::asio程序。它在linux (ubuntu 12.04, boost 1_48, gcc 4.6.4)上工作完美,但不能在Win7 (boost 1_55, vs2008express)。

在接受少量(从3到20)连接后,它挂起,并且不再接受连接。是窗户保护的问题吗?我关闭了防火墙和杀毒软件。

下面是供参考的代码:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Session : public boost::enable_shared_from_this<Session>
{
  public:
    Session(boost::asio::io_service &io_) : tcpSocket(io_)
    {
      std::cerr << "session ctor" << std::endl;
    }
    ~Session()
        {
      std::cerr << "session Dtor" << std::endl;
    }
    boost::asio::ip::tcp::socket& getTcpSocket() { return this->tcpSocket; }
private:
    boost::asio::ip::tcp::socket tcpSocket;
};
class Server
{
public:
    static const unsigned int defaultPort = 55550;
    Server();
    void start();
private:
    boost::asio::io_service io;
    boost::asio::ip::tcp::acceptor acceptor;
    void startAccept();
    void handleAccept(boost::shared_ptr<Session> s_,
          const boost::system::error_code& e_);
};
Server::Server()
    : acceptor(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), defaultPort))
{
}
void Server::start()
{
    this->startAccept();
    this->io.run();
}
void Server::startAccept()
{
    boost::shared_ptr<Session> s(new Session(io));
    acceptor.async_accept(s->getTcpSocket(), boost::bind(&Server::handleAccept,
                           this, s, boost::asio::placeholders::error));
}
void Server::handleAccept(boost::shared_ptr<Session> s_,
      const boost::system::error_code& e_)
{
    std::cerr << "handleAccept" << std::endl;
    if(e_)
        std::cerr << e_ << std::endl;
    this->startAccept();
}
int main(int, char**)
{
  Server server;
  server.start();
}

编辑:

问题解决了。

可能是Win7接受程序需要重新使用地址的选项:即SO_REUSEADDR。
尝试将服务器构造函数更改为:

Server::Server()
: acceptor(io)
{
  boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), defaultPort);
  acceptor.open(endpoint.protocol());
  acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
  boost::system::error_code ec;
  acceptor.bind(endpoint, ec);
  if(ec)
    // raise an exception or log this error, etc.
}