Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
Sockets 加速io_服务停止?_Sockets_Boost Asio_Boost Thread - Fatal编程技术网

Sockets 加速io_服务停止?

Sockets 加速io_服务停止?,sockets,boost-asio,boost-thread,Sockets,Boost Asio,Boost Thread,我正在开发一个NPAPI插件,该插件允许在本地浏览器内部使用套接字,为此我正在使用Boost套接字 我现在的用法是打开套接字写一个会议,阅读,发送一个结束消息,然后关闭,然后重复(我知道每次关闭和打开都是愚蠢的,但我不能改变这一点) 问题是,在第二次打开后,我无法从套接字读取数据,直到las发生变化,我才能够打开写入,但从未得到返回的信息,现在io_服务线程似乎正在消亡 我已经阅读了很多教程和信息,但似乎没有人像我尝试的那样打开几个客户端套接字 下面是存储套接字信息和处理程序的类: Socket

我正在开发一个NPAPI插件,该插件允许在本地浏览器内部使用套接字,为此我正在使用Boost套接字

我现在的用法是打开套接字写一个会议,阅读,发送一个结束消息,然后关闭,然后重复(我知道每次关闭和打开都是愚蠢的,但我不能改变这一点)

问题是,在第二次打开后,我无法从套接字读取数据,直到las发生变化,我才能够打开写入,但从未得到返回的信息,现在io_服务线程似乎正在消亡

我已经阅读了很多教程和信息,但似乎没有人像我尝试的那样打开几个客户端套接字

下面是存储套接字信息和处理程序的类:

SocketInfo.hpp

class SocketInfo
{
public:
    void start_read();
    void handle_read(const boost::system::error_code& error, std::size_t bytes_transferred);

    FB::JSObjectPtr m_callback;
    boost::shared_ptr<boost::asio::ip::tcp::socket> m_socket;
    char data_[SOCKETS_API_BUFFER];
    int key;
    boost::shared_ptr<SocketsAPI> parent;
};

似乎io_service.run()刚刚停止,但线程仍在工作,io_服务未停止,因此我不确定会发生什么情况。

好的,我发现了错误,它比我想象的简单得多,只是抛出了一个异常,停止了一切,但当我在浏览器中使用它时,我没有注意到这一点

我仍然无法解决问题,因此您可以检查:以分享一些见解

void SocketInfo::start_read()
{
    parent->log("start_read" + boost::lexical_cast<std::string>(key));
    m_socket->async_receive(boost::asio::buffer(data_, SOCKETS_API_BUFFER),
        boost::bind(&SocketInfo::handle_read, this, 
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
}

void SocketInfo::handle_read(const boost::system::error_code& error,
        std::size_t bytes_transferred)
{
    if (!error) {
        parent->log("handle_read" + boost::lexical_cast<std::string>(key));
        std::string str(&data_[0], &data_[0] + bytes_transferred);
        m_callback->InvokeAsync("processData", FB::variant_list_of(str));
        start_read();
    } else {
        parent->log("error closing " + boost::lexical_cast<std::string>(key));
        m_callback->InvokeAsync("processCancel", FB::variant_list_of());
        parent->do_close(*this);
    }
}
class SocketsAPI : public FB::JSAPIAuto
{
public:
    SocketsAPI(const SocketsPtr& plugin, const FB::BrowserHostPtr& host) :
        m_plugin(plugin), m_host(host)          
    {
... FireBreath code here ...

        //Start thread with work
        workPtr.reset( new boost::asio::io_service::work(io_service));
        ioThreadPtr.reset(new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service)));

    }

    virtual ~SocketsAPI() {
        workPtr.reset();
        if (ioThreadPtr) {
            ioThreadPtr->join();
        }
    };

    //Socket Methods
    int open(const int port, const FB::JSObjectPtr &callback );
    void close(const int key);
    void write(const int key, const std::string data);

    // Method echo
    FB::variant echo(const FB::variant& msg);
    void do_close(const SocketInfo socket);
    void log(const std::string &str);

private:

    mapType sockets;

    boost::asio::io_service io_service;
    boost::shared_ptr<boost::thread> ioThreadPtr;
    boost::shared_ptr<boost::asio::io_service::work> workPtr;

    void checkOpen(const SocketInfo socket);
    void do_write(const std::string data, const SocketInfo socket);
    void start_read(const SocketInfo socket);
    void empty_handle(const boost::system::error_code& error);
    int getFirstEmpty();
    SocketInfo getSocket(const int key);
};
int SocketsAPI::open(const int port, const FB::JSObjectPtr &callback )
{
    log("open");
    boost::shared_ptr<SocketInfo> socket;
    socket.reset(new SocketInfo);
    socket->m_socket.reset(new boost::asio::ip::tcp::socket(io_service));
    socket->m_callback = callback;
    ip::tcp::endpoint tcp(ip::address::from_string("127.0.0.1"), port);

    boost::system::error_code errorcode;
    socket->m_socket->connect(tcp, errorcode);
    if (errorcode) {
        trace("Connection failed: ", errorcode.message());
        return -1;
    }
    log("conenected");
    boost::asio::socket_base::keep_alive o(true);
    socket->m_socket->set_option(o);
    int key = getFirstEmpty();
    socket->key = key;
    socket->parent.reset(this);
    sockets.insert ( std::pair<int,boost::shared_ptr<SocketInfo>>(key,socket));
    socket->start_read();
    if (io_service.stopped()) {
        log("Resetting service");
        io_service.reset();
    }
    return key;
}

void SocketsAPI::close(const int key)
{
    SocketInfo socket = getSocket(key);
    checkOpen(socket);
    log("close");
    io_service.post(boost::bind(&SocketsAPI::do_close, this, socket));
}

void SocketsAPI::write(const int key, const std::string data)
{
    log("write socket " + boost::lexical_cast<std::string>(key));
    SocketInfo socket = getSocket(key);
    checkOpen(socket);
    io_service.post(boost::bind(&SocketsAPI::do_write, this, Base64::decode(data), socket));
}

void SocketsAPI::checkOpen(const SocketInfo socket)
{
    log("checkOpen");
    if (!socket.m_socket || !socket.m_socket->is_open()) {
        trace("Socket not opened", "");
        throw FB::script_error("There is no open socket");
    }
}


void SocketsAPI::do_write(const std::string data,
                            const SocketInfo socket)
{
    log("do_write " + boost::lexical_cast<std::string>(socket.key));
    if (!socket.m_socket->is_open()) {
        return;
    }
    boost::asio::async_write(*(socket.m_socket.get()),
        boost::asio::buffer(&data[0], data.size()),
        boost::bind(&SocketsAPI::empty_handle, this, boost::asio::placeholders::error)
    );
}

void SocketsAPI::empty_handle(const boost::system::error_code& error)
{
    if (error) {
        trace("Error writing: ", error.message());
    }
}

void SocketsAPI::do_close(const SocketInfo socket)
{
    log("do_close");
    if (!socket.m_socket || !socket.m_socket->is_open()) {
        return;
    }   
    boost::system::error_code errorcode;
    socket.m_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
    if (errorcode) {
        trace("Closing failed: ", errorcode.message());
    }
    socket.m_socket->close(errorcode);
    if (errorcode) {
        trace("Closing2 failed: ", errorcode.message());
    }
    mapType::iterator iter = sockets.find(socket.key);
    if (iter != sockets.end()) {
        sockets.erase (iter);
    }
    log("do_close end");
}

int SocketsAPI::getFirstEmpty() {
    int i = 0;
    mapType::iterator iter;
    while(true) {
        iter = sockets.find(i);
        if (iter == sockets.end()) {
            return i;
        }
        i++;
    }
}

SocketInfo SocketsAPI::getSocket(const int key) {
    mapType::iterator iter = sockets.find(key);
    if (iter == sockets.end()) {
        trace("Socket not found", "");
        throw FB::script_error("Socket not found");
    }
    log("socket " + boost::lexical_cast<std::string>(key) +" found");
    return *iter->second.get();
}
open 
conenected 
start_read0 
write socket 0 
socket 0 found 
checkOpen 
do_write 0 
handle_read0 
start_read0 
write socket 0 
socket 0 found 
checkOpen 
do_write 0 
socket 0 found 
checkOpen 
close 
do_close 
do_close end 
open 
conenected 
start_read0 
write socket 0 
socket 0 found 
checkOpen