Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Boost.Asio、tcp::iostream和多线程_C++_Multithreading_Boost Asio - Fatal编程技术网

C++ Boost.Asio、tcp::iostream和多线程

C++ Boost.Asio、tcp::iostream和多线程,c++,multithreading,boost-asio,C++,Multithreading,Boost Asio,tl;dr 如何使基于tcp::iostream的服务器(如下代码所示)在单独的线程中接受多个连接 我正在尝试使用Boost.Asio为一个已经存在的库实现一个服务器/客户机接口,我一直在摸索。(是的,C++11之前的版本。请耐心听我说。) 使用tcp::iostream的理由。 由于环境的原因,整个服务器进程是可选的;i、 e.当使用端口=0调用客户机时,它将请求传递给本地处理程序实例。在其他情况下,它与服务器连接,希望在该端口号侦听,服务器将请求传递给服务器进程的处理程序实例 (严格来说,

tl;dr

如何使基于
tcp::iostream
的服务器(如下代码所示)在单独的线程中接受多个连接


我正在尝试使用Boost.Asio为一个已经存在的库实现一个服务器/客户机接口,我一直在摸索。(是的,C++11之前的版本。请耐心听我说。)

使用tcp::iostream的理由。

由于环境的原因,整个服务器进程是可选的;i、 e.当使用
端口=0
调用客户机时,它将请求传递给本地
处理程序
实例。在其他情况下,它与服务器连接,希望在该端口号侦听,服务器将请求传递给服务器进程的
处理程序
实例

(严格来说,这都是127.0.0.1。服务器的存在是因为多个
处理程序
实例之间存在显著的共享状态,因此,如果所有用户都将其请求发送到机器上运行的一台服务器,则在内存和启动时间方面会容易得多。“本地”,
port=0
选项存在,因为这样我就可以只使用一个基于服务器和本地使用的客户端可执行文件。)

无论如何。有,这让事情变得非常简单:

boost::asio::io_service io_service;

boost::asio::ip::tcp::endpoint endpoint( boost::asio::ip::tcp::v4(), port_ );
boost::asio::ip::tcp::acceptor acceptor( io_service, endpoint );

for (;;)
{
    boost::asio::ip::tcp::iostream stream;
    boost::system::error_code ec;
    acceptor.accept( *stream.rdbuf(), ec );
    if ( ! ec )
    {
        Handler( stream, stream ).run(); // <---- This is the "why"
    }
    else
    {
        throw ec.message();
    }
    stream.close();
}
boost::asio::io_服务io_服务;
boost::asio::ip::tcp::endpoint端点(boost::asio::ip::tcp::v4(),端口号);
boost::asio::ip::tcp::acceptor acceptor(io_服务,端点);
对于(;;)
{
boost::asio::ip::tcp::iostream流;
boost::system::error_code ec;
acceptor.accept(*stream.rdbuf(),ec);
如果(!ec)
{

Handler(stream,stream).run();//我想我微妙地忽略了这里的问题。它与Asio无关:

#define BOOST_THREAD_USES_MOVE
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <boost/asio.hpp>
#include <boost/asio/basic_socket_iostream.hpp>
#include <boost/thread.hpp>
#include <iostream>
#include <list>

struct Handler {
    std::istream& is;
    std::ostream& os;

    Handler(std::istream& is, std::ostream& os) : is(is), os(os){}
    void run() {
        std::cout << __PRETTY_FUNCTION__ << ":" << __LINE__ << std::endl;
        std::string line;

        while (getline(is, line)) {
            std::reverse(line.begin(), line.end());
            os << line << std::endl;
        }
    }
};

struct SocketRequest : boost::enable_shared_from_this<SocketRequest> {
    boost::asio::ip::tcp::iostream stream;

    void start() {
        boost::async(boost::launch::async, boost::bind(&SocketRequest::do_run, shared_from_this()));
    }

  private:
    void do_run() {
        return Handler(stream, stream).run();
    }
};

int main() {
    boost::asio::io_service io_service;

    unsigned short port_ = 6767;
    boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port_);
    boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint);

    for (;;)
    {
        boost::shared_ptr<SocketRequest> req = boost::make_shared<SocketRequest>();

        acceptor.accept(*req->stream.rdbuf());
        req->start();
    }
}

我想你在gamedev上遇到过某个教程吗?我可以帮你找到它,但几年前我用它来做io_服务/tcp的事情。据我回忆,io_服务/run是一种制作一组线程的方法,可以做任何你喜欢的事情,但是要与asio的各种套接字等一起使用。找到它,碰巧是在我心里favourites@Carlos再添加一个教程有什么帮助?@DevSolar,为每个处理程序启动一个线程,然后只将iostream或socket传递给它怎么样?@sehe:但是我需要为每个
处理程序
单独设置一个
tcp::iostream
,不是吗?我在这里使用了c++11线程来提高速度,显然你会为c++0使用Boost线程3兼容性我很抱歉问你这个问题,但是你能把它转换成C++03/Boost.Thread-using代码吗?看看(同样不熟悉的)
std::future
中穿插着Boost的部分。我正在努力掌握的Asio代码在某种程度上加剧了我对过于密集而无法“获取”的沮丧或者,换言之,Boost文档中的所有多线程示例都是关于多次调用
io_服务::run()
。您的示例甚至一次都没有调用
io_服务::run()
。我对代码看得很清楚,但我无法理解其背后的概念-(哈哈-C++03中的Boost Future和Boost Move…很复杂。我还不知道如何使用,但在您的情况下,您可能不关心返回:这里有一个start
io\u service::run()
用于异步使用
(for req in HELLO BYE; do sleep 1; netcat 127.0.0.1 6767 <<< "$req"; done)&
void Handler::run():16
OLLEH
void Handler::run():16
EYB