V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fyyz
V2EX  ›  C

问个 Asio 的问题,为什么启用 server 的代码若写进 if 代码块里就无法运行 server?

  •  
  •   fyyz · 2017-10-24 11:13:52 +08:00 · 1793 次点击
    这是一个创建于 2616 天前的主题,其中的信息可能已经有所发展或是发生改变。
    //
    // async_tcp_echo_server.cpp
    // ~~~~~~~~~~~~~~~~~~~~~~~~~
    //
    // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
    //
    // Distributed under the Boost Software License, Version 1.0. (See accompanying
    // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
    //
    
    #include <cstdlib>
    #include <iostream>
    #include <memory>
    #include <utility>
    #include <boost/asio.hpp>
    
    using boost::asio::ip::tcp;
    
    class session
    	: public std::enable_shared_from_this<session>
    {
    public:
    	session(tcp::socket socket)
    		: socket_(std::move(socket))
    	{
    	}
    
    	void start()
    	{
    		do_read();
    	}
    
    private:
    	void do_read()
    	{
    		auto self(shared_from_this());
    		socket_.async_read_some(boost::asio::buffer(data_, max_length),
    			[this, self](boost::system::error_code ec, std::size_t length)
    		{
    			if (!ec)
    			{
    				do_write(length);
    			}
    		});
    	}
    
    	void do_write(std::size_t length)
    	{
    		auto self(shared_from_this());
    		boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
    			[this, self](boost::system::error_code ec, std::size_t /*length*/)
    		{
    			if (!ec)
    			{
    				do_read();
    			}
    		});
    	}
    
    	tcp::socket socket_;
    	enum { max_length = 1024 };
    	char data_[max_length];
    };
    
    class server
    {
    public:
    	server(boost::asio::io_service& io_service, short port)
    		: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
    		socket_(io_service)
    	{
    		do_accept();
    	}
    
    private:
    	void do_accept()
    	{
    		acceptor_.async_accept(socket_,
    			[this](boost::system::error_code ec)
    		{
    			if (!ec)
    			{
    				std::make_shared<session>(std::move(socket_))->start();
    			}
    
    			do_accept();
    		});
    	}
    
    	tcp::acceptor acceptor_;
    	tcp::socket socket_;
    };
    
    int main(int argc, char* argv[])
    {
    	try
    	{
    		if (argc != 2)
    		{
    			std::cerr << "Usage: async_tcp_echo_server <port>\n";
    			return 1;
    		}
    
    		boost::asio::io_service io_service;
    
    		if (std::atoi(argv[1]) % 2 == 0)
    		{
    			std::cout << 1 << std::endl; //此处有断点
    			server s(io_service, std::atoi(argv[1]));
    		}
    		
    
    		io_service.run();
    	}
    	catch (std::exception& e)
    	{
    		std::cerr << "Exception: " << e.what() << "\n";
    	}
    
    	return 0;
    }
    
    

    这段代码和 boost 官网的代码基本上完全一样,就是 main 函数里我多加了一个 [ if (std::atoi(argv[1]) % 2 == 0)] 。

    其实我自己的代码逻辑和这个是不一样的,但是我自己也是有一个 if,根据 if 的 true/false 设定 server 的启动参数,结果我发现我的代码完全可以跑到 if 的语句块里面,但是连端口都不会绑定。一开始我以为我自己的代码写错了,后来拿官网的代码一试也是如此,这是为什么?

    5 条回复    2017-10-24 12:13:11 +08:00
    fyyz
        1
    fyyz  
    OP
       2017-10-24 11:17:35 +08:00
    突然明白了,可能是出了 if 的作用域,导致 server 对象被释放了
    shibingsw
        2
    shibingsw  
       2017-10-24 11:25:07 +08:00
    @fyyz 是的
    bramblex
        3
    bramblex  
       2017-10-24 11:27:55 +08:00
    活捉
    fyyz
        4
    fyyz  
    OP
       2017-10-24 11:31:24 +08:00
    @bramblex 么么哒
    fyyz
        5
    fyyz  
    OP
       2017-10-24 12:13:11 +08:00
    用了 std::unique_ptr,问题彻底解决了~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2711 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 10:05 · PVG 18:05 · LAX 02:05 · JFK 05:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.