![](/img/trans.png)
[英]Why does boost::asio::ip::tcp::basic_stream_socket::available have a long runtime?
[英]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
不再有效,所以我已經嘗試了相關的poll
和run
函數,但沒有成功。
我也試圖取代boost::asio::buffer
帶boost::asio::mutable_buffer
和boost::asio::mutable_buffer
。 但是,完全相同的代碼在第一種方法中有效,所以我懷疑函數調用沒問題!
根據注釋sock
, SocketManager
io_service
和acceptor
成員被初始化為指向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
成員首先聲明,因為它必須在sock
和acceptor
之前初始化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.