使用POCO框架

时间:2018-11-30 08:38:23

标签: c++ sockets openssl poco

我遇到问题,然后尝试使用代理中的Poco基础与服务器重新连接。在连接会话结束时,我从服务器收到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()上的异常。

一种解决方法是使用shutdown标识套接字状态

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

但不合法,BCS SSL* ssl也是SecureSocketImpl _impl的私有字段,也是ServerSocketImpl的私有字段。

您遇到过此问题吗?

这是screen of wireshark

1 个答案:

答案 0 :(得分:0)

好的,直到POCO注意该问题,该问题才能解决。我建议我的方式。

在我的情况下,服务器未发送SSL_shutdown,因此我的套接字已打开。

您以前应该检查套接字为空,并禁止该异常。之后,您可以检查,该服务器已在重新连接之前发送了SSL_shutdown()。然后,您应该使用重新连接来恢复会话。

Here是说明如何通过黑客检查套接字状态的方法。

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);
    }
};

¯\ _(ツ)_ /¯