世界杯预选赛中国队赛程_世界杯多少年一次 - fybstd.com


asio 优雅关闭连接

2025-06-13 17:40:02 - 20世界杯

http://www.cnblogs.com/yyzybb/p/3795532.html

强制关闭

#include

#include

#include

#include

#include

typedef boost::shared_ptr socket_ptr_t;

typedef boost::array buffer_t;

typedef boost::shared_ptr buffer_ptr_t;

// 异步读数据回调函数

void on_read(boost::system::error_code ec

, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)

{

if (ec) // 连接失败, 输出错误码

{

std::cout << "async read error:" << ec.message() << std::endl;

}

}

// 异步写数据回调函数

void on_write(boost::system::error_code ec

, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)

{

if (ec) // 连接失败, 输出错误码

{

std::cout << "async write error:" << ec.message() << std::endl;

}

}

// 异步连接回调函数

void on_accept(boost::system::error_code ec, socket_ptr_t socket_ptr)

{

if (ec) // 连接失败, 输出错误码

{

std::cout << "async accept error:" << ec.message() << std::endl;

}

else // 连接成功

{

std::cout << "async accept from (" << socket_ptr->remote_endpoint() << ")" << std::endl;

{

buffer_ptr_t buffer_ptr(new buffer_t);

strcpy_s((char*)buffer_ptr->begin(), buffer_t::size(), "abcdefg");

socket_ptr->async_write_some(boost::asio::buffer(buffer_ptr.get(), strlen((char*)buffer_ptr->begin()))

, boost::bind(&on_write, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred

, socket_ptr, buffer_ptr));

}

{

buffer_ptr_t buffer_ptr(new buffer_t);

socket_ptr->async_read_some(boost::asio::buffer(buffer_ptr.get(), buffer_t::size())

, boost::bind(&on_read, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred

, socket_ptr, buffer_ptr));

}

/// 强制关闭连接

socket_ptr->close(ec);

if (ec)

std::cout << "close error:" << ec.message() << std::endl;

}

}

int main()

{

boost::asio::io_service ios; // 创建io_service对象

boost::asio::ip::tcp::endpoint addr(

boost::asio::ip::address::from_string("0.0.0.0"), 12345); // server端地址

boost::asio::ip::tcp::acceptor acceptor(ios, addr, false); // 创建acceptor对象

socket_ptr_t socket_ptr(new boost::asio::ip::tcp::socket(ios));

acceptor.async_accept(*socket_ptr

, boost::bind(&on_accept, boost::asio::placeholders::error, socket_ptr)); // 调用异步accept请求

socket_ptr.reset();

ios.run(); // 调用io_service::run, 等待异步操作结果

std::cout << "press enter key...";

std::cin.get();

return 0;

}

这个例子中,接受到客户端的连接后,立即发起异步读请求和异步写请求,然后立即强制关闭socket。

优雅关闭

#include

#include

#include

#include

#include

typedef boost::shared_ptr socket_ptr_t;

typedef boost::array buffer_t;

typedef boost::shared_ptr buffer_ptr_t;

// 异步读数据回调函数

void on_read(boost::system::error_code ec

, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)

{

static int si = 0;

if (ec) // 连接失败, 输出错误码

{

std::cout << "async read(" << si++ << ") error:" << ec.message() << std::endl;

socket_ptr->shutdown(boost::asio::socket_base::shutdown_receive, ec);

socket_ptr->close(ec);

if (ec)

std::cout << "close error:" << ec.message() << std::endl;

}

else

{ //直到读完了,才进行优雅关闭

std::cout << "read(" << si++ << ") len:" << len << std::endl;

socket_ptr->async_read_some(boost::asio::buffer(buffer_ptr.get(), buffer_t::size())

, boost::bind(&on_read, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred

, socket_ptr, buffer_ptr));

}

}

// 异步写数据回调函数

void on_write(boost::system::error_code ec

, std::size_t len, socket_ptr_t socket_ptr, buffer_ptr_t buffer_ptr)

{

if (ec) // 连接失败, 输出错误码

{

std::cout << "async write error:" << ec.message() << std::endl;

}

else

{

/// 优雅地关闭连接

socket_ptr->shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);

if (ec)

std::cout << "shutdown send error:" << ec.message() << std::endl;

}

}

// 异步连接回调函数

void on_accept(boost::system::error_code ec, socket_ptr_t socket_ptr)

{

if (ec) // 连接失败, 输出错误码

{

std::cout << "async accept error:" << ec.message() << std::endl;

}

else // 连接成功

{

std::cout << "async accept from (" << socket_ptr->remote_endpoint() << ")" << std::endl;

{

buffer_ptr_t buffer_ptr(new buffer_t);

socket_ptr->async_read_some(boost::asio::buffer(buffer_ptr.get(), buffer_t::size())

, boost::bind(&on_read, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred

, socket_ptr, buffer_ptr));

}

{

buffer_ptr_t buffer_ptr(new buffer_t);

strcpy_s((char*)buffer_ptr->begin(), buffer_t::size(), "abcdefg");

socket_ptr->async_write_some(boost::asio::buffer(buffer_ptr.get(), strlen((char*)buffer_ptr->begin()))

, boost::bind(&on_write, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred

, socket_ptr, buffer_ptr));

}

}

}

int main()

{

boost::asio::io_service ios; // 创建io_service对象

boost::asio::ip::tcp::endpoint addr(

boost::asio::ip::address::from_string("0.0.0.0"), 12345); // server端地址

boost::asio::ip::tcp::acceptor acceptor(ios, addr, false); // 创建acceptor对象

socket_ptr_t socket_ptr(new boost::asio::ip::tcp::socket(ios));

acceptor.async_accept(*socket_ptr

, boost::bind(&on_accept, boost::asio::placeholders::error, socket_ptr)); // 调用异步accept请求

socket_ptr.reset();

ios.run(); // 调用io_service::run, 等待异步操作结果

std::cout << "press enter key...";

std::cin.get();

return 0;

}

在这个例子中,接收到客户端的连接并向客户端发送数据以后,先关闭socket的发送通道,然后等待socket接收缓冲区中的数据全部read出来以后,再关闭socket的接收通道。

此时,socket的接收和发送通道均以关闭,任何进程都无法使用此socket收发数据,但其所占用的系统资源并未释放,底层发送缓冲区中的数据也不保证已全部发出,需要在此之后执行close操作以便释放系统资源。

若在释放系统资源前希望底层发送缓冲区中的数据依然可以发出,则需在socket的linger属性中设置一个等待时间,以便有时间等待发送缓冲区中的数据发送完毕。

但linger中的值绝对不是越大越好,这是因为其原理是操作系统帮忙保留socket的资源以等待其发送缓冲区中的数据发送完毕,如果远端socket的一直未能接收数据便会导致本地socket一直等待下去,这对系统资源是极大的浪费。

因此,在需要处理大量连接的服务端,linger的值一定不可过大。