草庐IT

c++ - 连接后连接丢失 -> 服务器 TCP boost.ASIO

coder 2023-09-19 原文

我做了 boost 教程:异步 TCP 日间服务器 http://think-async.com/Asio/asio-1.1.1/doc/asio/tutorial/tutdaytime3.html 当我想测试它时,服务器正在运行,这很好,但如果我执行 nc -C localhost 4242,客户端会收到服务器的消息,但之后客户端会直接断开连接。

这里是我的代码:

#include "server.h"
#include "connection.h"

Server::Server(boost::asio::io_service& io_service) : accept(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 4242))
{
  wait_connection();
}

Server::~Server()
{

}

void Server::wait_connection()
{
  std::cout << "wait_connection" << std::endl;
  boost::shared_ptr<Connection> new_connection =
  Connection::start_connection(accept.get_io_service());

  accept.async_accept(new_connection->getSocket(), boost::bind(&Server::callback_accept, this, new_connection, boost::asio::placeholders::error));
}

void Server::callback_accept(boost::shared_ptr<Connection> new_connection, const boost::system::error_code &error)
{
  if (!error)
  {
    new_connection->send_message_to_client();
    wait_connection();
  }
}


Connection::Connection(boost::asio::io_service& io_service) : socket(io_service)
{

}

Connection::~Connection()
{
  std::cout << "destructeur Connection" << std::endl;
}

boost::shared_ptr<Connection> Connection::start_connection(boost::asio::io_service& io_service)
{
  return (boost::shared_ptr<Connection>(new Connection(io_service)));
}

boost::asio::ip::tcp::socket& Connection::getSocket()
{
  return (this->socket);
}

void Connection::send_message_to_client()
{
  message = "Bienvenue!\n";

  boost::asio::async_write(socket, boost::asio::buffer(message), boost::bind(&Connection::callback_send, shared_from_this()));
}

void Connection::callback_send()
{

}

int main()
{
  try {

    boost::asio::io_service io_service;
    Server server(io_service);
    io_service.run();
  }
  catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  }

  return (0);
}

#ifndef SERVER_H
#define SERVER_H

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include "connection.h"

class Server {
private:
  boost::asio::ip::tcp::acceptor accept;

public:
  Server (boost::asio::io_service&);
 ~Server ();

  void wait_connection();
  void callback_accept(boost::shared_ptr<Connection> new_connection, const boost::system::error_code& error);

};

#endif /* end of include guard: SERVER_H */


#ifndef CONNECTION_H
#define CONNECTION_H

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

class Connection : public boost::enable_shared_from_this<Connection>
{
private:
  boost::asio::ip::tcp::socket socket;
  std::string message;
public:
  Connection (boost::asio::io_service&);
  ~Connection ();

  static boost::shared_ptr<Connection> start_connection(boost::asio::io_service&);
  boost::asio::ip::tcp::socket& getSocket();
  void send_message_to_client();
  void callback_send();
};

#endif /* end of include guard: CONNECTION_H */

最佳答案

症结:共享指针使对象保持事件状态,直到引用计数达到零。

您在此处将消息写入客户端。完成后,您将执行 callback_send:

boost::asio::async_write(socket, boost::asio::buffer(message),
                         boost::bind(&Connection::callback_send, shared_from_this()));

那么我们接下来要做什么?

void Connection::callback_send() {}

哦。那是……不多。所以。没有什么?

嗯。几乎没有

这是“不做某事也是做某事”的情况。通过发布另一个使套接字/连接保持事件状态的操作,这意味着连接将被释放。

因为没有其他东西将 shared_ptr 保留到连接,shared_ptr 将删除连接(调用析构函数,您可以看到它,因为它每次都会打印 destructeur Connection)。

所以。解决办法是什么? 我们不知道。在您说“欢迎”之后,您想做什么取决于您。在最有可能的情况下,您将希望等待来自客户端的某种消息。这将涉及一些 async_read* 调用,它可以愉快地保持连接(再次是 shared_from_this())。

演示

假设您想要继续接收线路,并且您将相同的线路发回,相反:

void Connection::callback_send() {
    boost::asio::async_read_until(socket, request, "\n",
                             boost::bind(&Connection::on_request_received, shared_from_this(),
                                 boost::asio::placeholders::error,
                                 boost::asio::placeholders::bytes_transferred));
}

void Connection::on_request_received(boost::system::error_code ec, size_t n) {
    if (ec && !((ec == boost::asio::error::eof) && n))
        std::cout << "Receive error: " << ec.message() << "\n";
    else
    {
        std::cout << "Received request\n";

        {
            std::istream is(&request);
            std::getline(is, message);
        }

        std::reverse(message.begin(), message.end());

        std::cout << "Sending response: " << message << "\n";

        message += '\n';

        if (!ec) boost::asio::async_write(socket, boost::asio::buffer(message),
               boost::bind(&Connection::callback_send, shared_from_this()));
    }
}

关于c++ - 连接后连接丢失 -> 服务器 TCP boost.ASIO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46449276/

有关c++ - 连接后连接丢失 -> 服务器 TCP boost.ASIO的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  4. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  5. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  6. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  7. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  8. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  9. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  10. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

随机推荐