2012-06-15 110 views
2

我想要一个有状态的通信,但不喜欢boost的echo服务器示例。我的套接字将准备永久阅读,每当它接收到新数据时,它将调用虚拟方法dataAvailable(string)但是它可以随时做async_writeboost asio有状态套接字接口

void connected(const boost::system::error_code &ec) { 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
     boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
     boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
    // boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
    // boost::asio::placeholders::bytes_transferred)); 
    std::cout << ">> Session::connected()" << std::endl; 
} 

void handler_read(const boost::system::error_code &ec, size_t bytes_transferred) { 
    if(ec) { 
    std::cout << ec.message() << std::endl; 
    } else { 
    //std::copy(_buffer, _buffer+bytes_transferred, data.begin()); 
    std::string data(_buffer, _buffer+bytes_transferred); 
    std::cout << ">> Session[ " << id() << "]" << "::handler_read(): " << 
      bytes_transferred << " " << data << std::endl; 
    boost::asio::async_write(_socket, boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_write, this, 
      boost::asio::placeholders::error)); 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
     // boost::bind(&Session::handler_read, this, 
     // boost::asio::placeholders::error, 
     // boost::asio::placeholders::bytes_transferred)); 
     //call dataAvailable(_buffer); 
    } 
} 

void handler_write(const boost::system::error_code &ec) { 
    if(ec) { 
    std::cout << ec.message() << std::endl; 
    } else { 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
     // boost::bind(&Session::handler_read, this, 
     // boost::asio::placeholders::error, 
     // boost::asio::placeholders::bytes_transferred)); 
    } 
} 
  1. 这是实现好?因为多个线程可能会执行读取和写入操作。其中写操作是在矩阵
  2. 为什么它不工作(不Echo的接收到的字符串)某些细胞的更新用,当我使用的async_read代替async_read_some
  3. 在我的听力服务器,我无处调用listen方法。但仍然在工作。那么为什么有一种听法?以及何时使用?
  4. 我想从客户端退出客户端套接字时收到通知。例如客户已关闭连接。我该怎么做 ?我的方式是读 read_handler但这是唯一的方法吗?
  5. 我有一个Session类,每个会话都有一个套接字。我在会话管理器中存储Session*集合。现在当我关闭一个套接字并delete它会话变为空。它可能发生在vector的中间。那么如何安全地删除那个会话?
+0

你可以用[self contained reproduction](http://sscce.org/)来编辑你的问题,这样我们就可以看到它不起作用了吗?在你发布的代码片段中没有明显的错误。 –

回答

0

你的代码有一个严重的问题。想象一下,你有不对称的网络链接,并且能够比发送更快地接收。

  1. 接收消息
  2. 待办事项ASYNC_WRITE(但需要时间)
  3. 计划未来阅读
  4. 收到一条消息
  5. 做第二ASYNC_WRITE(第一个是还没有完成,你会得到垃圾一个链接的另一端)
  6. 安排下一个阅读
  7. 第一个async_write完成并计划一个async_read_some

总之,你要求asio一次完成多个读写操作。

为什么它不工作(不Echo的接收到的字符串)当我使用的async_read_some

你发送足够的数据(max_length)async_read呢?也许你想使用boost::asio::transfer_at_least(min_length)

在我的侦听服务器中,我无处调用listen方法。但仍然在工作。那么为什么有一种听法?以及何时使用?

您可能在某处创建acceptor对象。

我想从客户端退出客户端套接字时收到通知。例如客户已关闭连接。我该怎么做 ?我出来的方式是通过阅读read_handler中的文件结束但是唯一的方式?

您可以创建包装,这将采取EOF并做一些清理。然后用wrapper封装所有的自定义处理程序,并将其作为处理函数传递给:: asio。如果你愿意,这样你只有一个地方可以处理EOF错误。

我有一个Session类,每个会话都有一个套接字。我正在会话管理器中存储Session *集合。现在当我关闭套接字并删除它时,会话变为空。它可能发生在矢量的中间。那么如何安全地删除那个空会话?

使用boost::shared_ptr在处理程序等,并boost::shared_ptrboost::weak_ptr在会话管理器的矢量。

相关问题