使用 POCO Frame 识别半开连接中套接字的状态
Identify state of socket in half-open connection using POCO Frame
我有一个问题,然后我正在尝试重新连接服务器,使用我的代理中的 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() 上收到异常。
解决这个问题的一种方法是使用关闭来识别套接字状态
if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)
reconnect();
但它不合法,bcs SSL* ssl
是 SecureSocketImpl _impl
的私有字段,也是 ServerSocketImpl
的私有字段。
你遇到过这个问题吗?
这是screen of wireshark。
好的,这个问题要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);
}
};
¯\_(ツ)_/¯
我有一个问题,然后我正在尝试重新连接服务器,使用我的代理中的 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() 上收到异常。
解决这个问题的一种方法是使用关闭来识别套接字状态
if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)
reconnect();
但它不合法,bcs SSL* ssl
是 SecureSocketImpl _impl
的私有字段,也是 ServerSocketImpl
的私有字段。
你遇到过这个问题吗?
这是screen of wireshark。
好的,这个问题要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);
}
};
¯\_(ツ)_/¯