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

2017-10-24 11:13:52 +08:00
 fyyz
//
// 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 的语句块里面,但是连端口都不会绑定。一开始我以为我自己的代码写错了,后来拿官网的代码一试也是如此,这是为什么?

1681 次点击
所在节点    C
5 条回复
fyyz
2017-10-24 11:17:35 +08:00
突然明白了,可能是出了 if 的作用域,导致 server 对象被释放了
shibingsw
2017-10-24 11:25:07 +08:00
@fyyz 是的
bramblex
2017-10-24 11:27:55 +08:00
活捉
fyyz
2017-10-24 11:31:24 +08:00
@bramblex 么么哒
fyyz
2017-10-24 12:13:11 +08:00
用了 std::unique_ptr,问题彻底解决了~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/400174

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX