I have copied the chat-example from the boost examples.
- server code: https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/chat/chat_server.cpp
- chat_message.hpp: https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/chat/chat_message.hpp
- client code: https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/chat/chat_client.cpp
In chat_server.cpp
, I have added a cout
in chat_room::leave
to get notified when a client leaves. In chat_server
, I tried to configure TCP keepalive according to this SO answer:
// additional includes that I have added
#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2spi.h>
#include <mstcpip.h>
#include <windows.h>
// ----
class chat_server {
public:
chat_server(boost::asio::io_service& io_service,
const tcp::endpoint& endpoint)
: acceptor_(io_service, endpoint),
socket_(io_service) {
do_accept();
}
private:
void do_accept() {
acceptor_.async_accept(socket_,
[this](boost::system::error_code ec) {
if(!ec) {
unsigned long val = 1;
int res = setsockopt(socket_.native_handle(), SOL_SOCKET, SO_KEEPALIVE, (char*) &val, sizeof val);
if(res) std::cout << "Can't set sockopt!" << std::endl;
tcp_keepalive alive;
alive.onoff = TRUE;
alive.keepalivetime = 1000;
alive.keepaliveinterval = 1000;
DWORD bytes_ret = 0;
res = WSAIoctl(socket_.native_handle(), SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0,
&bytes_ret, NULL, NULL);
if(res) std::cout << "Can't set TCP keepalive!" << std::endl;
std::make_shared<chat_session>(std::move(socket_), room_)->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
tcp::socket socket_;
chat_room room_;
};
My test setup is to run the server on my local machine. The client runs on a "VMware Workstation 15 Player"-virtual machine, where NAT is used as network adapter. When I connect to the server and uncheck the "Connected"-checkbox in Virtual Machine Settings (should be the same as unplugging the network cable), I would expect to see the output of chat_room::leave
in the console, but it seems, that the server even after a few minutes thinks that the client is still connected.
How can I configure the TCP keepalive appropriately? (I would prefer a cross-platform solution which works on Linux too, but if it works on windows, it's better than nothing)
Edit: I have monitored the sent data with Wireshark and found out that no keep-alive packets were sent. What could cause this?