簡體   English   中英

為什么這個 Boost TCP 套接字以一種方法工作而不是另一種方法?

[英]Why does this Boost TCP socket work in one method and not in another?

我想在一個方法中建立一個套接字連接,並在一個類的另一個方法中使用這個連接。 雖然在第一種方法(我建立連接的地方)中,我可以根據需要從套接字讀取和向套接字寫入,但在第二種方法中,我總是收到Bad file descriptor錯誤。 請注意,我使用的是1.65.1版的 Boost。

我創建了一個小的可重現示例(我添加了一些日志以進行澄清):

代碼.h

#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class SocketManager {
    tcp::socket *sock;
    boost::asio::io_service *io_service;
    tcp::acceptor *acceptor;

    public:
        virtual void initialize();  // works
        virtual void evaluate();  // fails
};

代碼.cc

#include "code.h"
#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;
using namespace std;


int main() {
    SocketManager sm;
    sm.initialize();
    sm.evaluate();
    return 0;
}

void SocketManager::initialize() {
    boost::asio::io_service _io_service;
    io_service = &_io_service;

    tcp::acceptor a(*io_service, tcp::endpoint(tcp::v4(), 1337));
    acceptor = &a;

    tcp::socket sock_(*io_service);
    sock = &sock_;

    a.accept(*sock);

    char data[1024];
    boost::system::error_code error;
    size_t length = sock->read_some(boost::asio::buffer(data), error);
    if (error)
        throw boost::system::system_error(error);  // No Error here!

    boost::asio::write(*sock, boost::asio::buffer(data, length));

    cout << io_service->stopped() << endl;  // prints 0
    cout << acceptor->is_open() << endl;  // prints 1
    cout << sock->is_open() << endl;  // prints 1
}

void SocketManager::evaluate() {
    cout << io_service->stopped() << endl;  // prints 0
    cout << acceptor->is_open() << endl;  // prints 1
    cout << sock->is_open() << endl;  // prints 1

    char data[1024];
    boost::system::error_code error;
    size_t length = sock->read_some(boost::asio::buffer(data), error);
    if (error)
        throw boost::system::system_error(error);  // Error: "Bad file descriptor"
}

與客戶端一起使用時上述代碼的輸出:

root@5531547d4baf:/cpp# ./a.out 
0
1
1
0
1
1
terminate called after throwing an instance of 'boost::system::system_error'
  what():  Bad file descriptor
Aborted

請注意,拋出錯誤的代碼在兩種方法中是完全相同的代碼(在第一個方法中它沒有任何錯誤,而在第二個方法中它拋出一個Bad file descriptor錯誤)。

我懷疑切換到新函數時io_service不再有效,所以我已經嘗試了相關的pollrun函數,但沒有成功。

我也試圖取代boost::asio::bufferboost::asio::mutable_bufferboost::asio::mutable_buffer 但是,完全相同的代碼在第一種方法中有效,所以我懷疑函數調用沒問題!

根據注釋sockSocketManager io_serviceacceptor成員被初始化為指向SocketManager::initialize局部變量。 完成后,您將獲得懸空指針。

我在這里根本看不到任何使用指針的理由。 只需使它們成為非指針數據成員並在構造函數中初始化它們(未經測試)...

class SocketManager {
    boost::asio::io_service io_service;
    tcp::acceptor           acceptor;
    tcp::socket             sock;
public:
    SocketManager ()
      : acceptor(io_service, tcp::endpoint(tcp::v4(), 1337))
      , sock(io_service)
      {}
      ...
};

請注意, io_service成員首先聲明,因為它必須sockacceptor之前初始化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM