gpt4 book ai didi

c++ - 使用 shared_ptr c++ boost tcp 套接字

转载 作者:可可西里 更新时间:2023-11-01 02:39:52 25 4
gpt4 key购买 nike

我正在尝试使用 C++ 中的新类来包装 boost TCP。当我直接调用 boost 函数时,一切都很顺利。但是,当关闭包装在类函数中时,我无法调用套接字关闭。请帮忙看看下面的代码。

类定义:

typedef boost::shared_ptr<tcp::socket> Socket;
class TCPConnector{
public :
bool isConnected;
Socket sock;
string ip;
int port;
TCPConnector(string ip, int port);

void Close();
bool Connect();
};

功能:

TCPConnector::TCPConnector(string ip,int port):ip(ip),port(port)
{

}

void TCPConnector::Close() {
boost::system::error_code error;
if (!isConnected)
return;
isConnected = false;

try {

sock->shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
cout << "ShutDown" << endl;
if (error)
throw boost::system::system_error(error);
sock->close(error);
if (error)
throw boost::system::system_error(error);
} catch (exception& e) {
cout << "#TCPConnector::Close()#" << e.what() << endl;
}
}

主要功能:

int main(int argc, char* argv[]) {
try {
TCPConnector* conn = new TCPConnector("127.0.0.1",8088);

for (int i = 0; i < 2; i++) {
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(tcp::v4(), "127.0.0.1", "8088");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
conn->sock.reset(new tcp::socket(io_service));
conn->sock->connect(*endpoint_iterator);
cout << "Connected" << endl;
boost::thread acceptorThread(boost::bind(receive,conn));
sleep(1);
unsigned char msg[8] = { 0, 6, 55, 56, 55, 56, 55, 0 };
boost::system::error_code error;
try {

boost::asio::write(*conn->sock, boost::asio::buffer(msg, 8),
boost::asio::transfer_all(), error);
cout << "Sent" << endl;
if (error)
throw boost::system::system_error(error);
conn->sock->shutdown(boost::asio::ip::tcp::socket::shutdown_both,
error);
if (error)
throw boost::system::system_error(error);




conn->sock->close(error);//close socket directly , the result is ok
//conn->Close();// close by calling functions, it causes problems.





cout << "Closed" << endl;
if (error)
throw boost::system::system_error(error);
io_service.stop();
} catch (std::exception& e) {
std::cerr << "Exception in thread: " << e.what() << "\n";
}
cout << "Sleep" << endl;
sleep(2);
cout << "Wake up" << endl;
}
} catch (std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}

这两行给出了不同的行为。我不知道为什么第二个会导致问题。

conn->sock->close(error);//close socket directly , the result is ok
conn->Close();// close by calling functions, it causes problems.

mutex: Invalid argument 打印在

sock->close(error);
if (error)
throw boost::system::system_error(error);

问题与 shared_ptr 有关吗?或者我错过了关闭套接字的重要事项?

感谢您的任何建议。

最佳答案

问题是 io_service 应该比 socket 长。

for 循环的第一次迭代中,语句 conn->sock.reset(new tcp::socket(io_service)); 调用析构函数上一次迭代的套接字。此析构函数访问先前迭代的 io_service 的元素(特别是它的互斥体),此时它们本身已被销毁。

要解决此问题,您可以将 io_service 移到 for 循环之外,或者您可以调用 conn->sock.reset();for 循环结束时调用 socket 的析构函数,同时 io_service 仍然有效。

关于c++ - 使用 shared_ptr c++ boost tcp 套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15126277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com