boost :: asio - не может установить значение keepalive - PullRequest
0 голосов
/ 25 апреля 2020

Я скопировал пример чата из примеров буста.

В chat_server.cpp я добавил cout в chat_room::leave, чтобы получить уведомляется, когда клиент уходит. В chat_server я попытался настроить поддержку активности TCP в соответствии с этим SO-ответом :

// 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_;
};

Моя тестовая настройка - запустить сервер на моей локальной машине. Клиент работает на виртуальной машине «VMware Workstation 15 Player», где NAT используется в качестве сетевого адаптера. Когда я подключаюсь к серверу и снимаю флажок «Подключено» в настройках виртуальной машины (должен совпадать с отключением сетевого кабеля), я ожидаю увидеть вывод chat_room::leave в консоли, но, похоже, что даже через несколько минут сервер считает, что клиент все еще подключен.

Как правильно настроить поддержку активности TCP? (Я бы предпочел кроссплатформенное решение, которое также работает на Linux, но если оно работает на windows, это лучше, чем ничего)

Редактировать: я проверил отправленные данные с помощью Wireshark и выяснил, что пакеты keep-alive не были отправлены. Что может вызвать это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...