Определите состояние сокета в полуоткрытом соединении, используя POCO Frame - PullRequest
0 голосов
/ 30 ноября 2018

У меня проблема, затем я пытаюсь переподключиться к серверу, используя Poco, лежащий в основе моего Proxy.В конце сеансов подключения я получаю пакет FIN, ACK с сервера.Затем TCP отправляет ACK, чтобы ответить серверу о получении FIN.Так что у меня полуоткрытое соединение.Мой сокет закрыт для чтения, но не для отправки.После нескольких секунд ожидания я отправляю http-запрос,

auto& requestStream = mSession->sendRequest(request);
Poco::StreamCopier::copyStream(request.stream(), requestStream);

auto& responseStream = mSession->receiveResponse(response);
Poco::StreamCopier::copyStream(responseStream, response.send());

TCP отправляет FIN, ACK и отправляет SYN, чтобы начать другой сеанс подключения, поэтому я получаю исключение по SSL_Read ().

OneЧтобы определить это, определите состояние сокета, используя shutdown

if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)
    reconnect();

, но это не разрешено, bcs SSL* ssl - это приватное поле SecureSocketImpl _impl, которое также является приватным полем ServerSocketImpl.

Вы когда-нибудь сталкивались с этой проблемой?

Это экран wireshark .

1 Ответ

0 голосов
/ 14 декабря 2018

Хорошо, эта проблема не будет решена, пока POCO не обратит на это внимание.Я предлагаю свой путь.

В моем случае сервер не отправил SSL_shutdown, поэтому мой сокет открыт.

Необходимо предварительно проверить, что сокет пуст, и исключить это исключение.После этого вы можете проверить, что сервер отправил SSL_shutdown () перед переподключением.Затем вы должны использовать Reconnect для восстановления вашего сеанса.

Здесь - описание того, как сделать хак для проверки состояния вашего сокета.

class HttpsClientSession : public HTTPSClientSession {

public:
    using Super::HTTPSClientSession;

    ostream& sendRequest(HTTPRequest& request) override {
            if (connected() && socket().poll(Poco::Timespan(0), Socket::SELECT_READ)) {
                    try {
                            peek();
                    } catch (const SSLConnectionUnexpectedlyClosedException&) {
                            reconnect();
                    }

                    auto sock = static_cast<SecureStreamSocketImpl*>(socket().impl());
                    auto ssl = PRIVATE_ACCESS(PRIVATE_ACCESS(*sock, _impl), _pSSL);

                    if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)
                            reconnect();
            }

            return HTTPSClientSession::sendRequest(request);
    }
};

¯ \ _ (ツ) _ / ¯

...