-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Version of Boost
1.88.0.
Actual and Expected Behavior
I am testing the behavior of an ip::tcp::socket (created by a call to ip::tcp::acceptor::async_accept) after the remote endpoint has closed the connection. What I expect is that any async_write_some call done on the local socket subsequent to ip::tcp::socket::close done by the remote socket should either return or fail with a Broken Pipe exception. Since I need to use coroutines, I am calling async_write_some with the use_awaitable Completion Token.
This is my code, written as a test case for Google Test:
TEST_F(TCPTest, CloseSocket)
{
using namespace boost::asio;
thread_pool pool{1};
const ip::address myAddress{ip::make_address("127.0.0.1")};
const ip::port_type myPort{54'321};
ip::tcp::acceptor acceptor(pool.get_executor(), ip::tcp::endpoint{myAddress, myPort});
ip::tcp::socket socket{pool.get_executor()};
socket.connect(ip::tcp::endpoint{myAddress, myPort});
auto acceptedSock = acceptor.async_accept(use_future).get();
socket.close();
const auto writeFunc{[](ip::tcp::socket& sock) -> awaitable<void> {
const std::string message{"hello\n"};
constexpr auto retries{10};
for(auto i{0}; i < retries; ++i) {
std::cout << "Try: " << i << "\n";
try {
co_await sock.async_write_some(buffer(message), use_awaitable);
} catch(const boost::system::system_error& e) {
std::cout << "Write exception: " << e.code() << '\n';
}
}
}};
auto future = co_spawn(pool.get_executor(), writeFunc(acceptedSock), use_future);
ASSERT_EQ(future.wait_for(testTimeout), std::future_status::ready);
}What I expect is that this test should write "Try: [number_of_retry]" 10 times (and also "Write exception: system:32" most of the times).
What it actually happens is that, after a few retries, the test hangs on a co_await sock.async_write_some call until timeout.
All relevant compiler information
I am using x86_64 GCC 13.3 on Ubuntu 24.04.