【问题标题】:How to correctly close a connection with Poco::HTTPSClientSession?如何正确关闭与 Poco::HTTPSClientSession 的连接?
【发布时间】:2013-12-13 08:36:59
【问题描述】:

Poco::HTTPSClientSession 遇到问题,不知道如何处理。

描述(或发生了什么)

使用Poco::HTTPSClientSession 类建立到服务器的HTTPS 连接。连接建立、密钥交换、初始数据交换运行良好。

客户端在会话建立后直接发送一个请求。使用了 HTTP 1.1 特性持久连接(即连接保持打开一段时间以处理额外的请求)。服务器等待一分钟 - 通过此连接不再接收请求 - 然后发送 close_notify 并关闭连接(使用 TCP FIN)。大约两分钟后,客户端想要发送下一个请求。客户端发送close_notify 并使用 TCP RST 关闭连接。

我的意见

客户端行为恕我直言不正确。正如您在RFC 6101 5.4.1. Closure Alerts 中看到的那样,对方应该立即关闭连接

要求对方以自己的 close_notify 警报响应并立即关闭连接,丢弃任何未决的写入。

我的问题

我不确定如何使用 Poco 处理这个问题。对我来说,看起来需要一些回调处理(在服务器发送close_notify 的时间点)。问题是,因为 'socket()' 方法在Poco::HTTPSClientSession 中受到保护,所以无法安装这样的close_notify 处理程序——甚至我也不知道是否有适当的回调。

您能否提示我在服务器发送close_notify 时正确关闭客户端HTTPS 连接的类/函数? [Joachim Pileborg回答后的补充]:是否需要从Poco::HTTPSClientSession继承才能正确处理close_notify

亲切的问候 - 安德烈亚斯

【问题讨论】:

  • 当您完成请求后,为什么不简单地破坏HTTPSClientSession 对象呢?当您需要发出另一个请求时,请创建一个新请求。
  • 这是因为在几秒钟内发送数百个请求时,也有高负载的时间。当这种情况发生时,这是无法预测的。在这些时候,每次建立 SSL 连接的开销都很高。
  • 那你有自己的超时时间吗?如果在设定的时间(秒?分钟?由您决定)内没有任何请求,则销毁该对象。
  • 抱歉 - 但我不想寻求解决方法。我的问题是:如何使用 Poco 正确处理这种情况?在这里进行一些(人为的)超时处理并没有真正帮助我。 (甚至每个服务器都可以有另一个超时时间。)库中应该有一些功能来处理这些异步关闭通知。
  • 收到关于关闭连接的通知的问题是,真正判断连接是否已被其他对等方很好地关闭的唯一方法是从套接字接收,然后它将返回零字节已收到。所以很难以独立于平台的方式异步处理这个问题。

标签: c++ https connection poco-libraries termination


【解决方案1】:

这是一个老问题,但由于没有任何可以接受的回答,我在这里提出了我的解决方案,如果它可以帮助某人的话。

在向服务器发送请求之前执行此操作。

if (mySession->socket().poll(0, Poco::Net::Socket::SELECT_READ) && (mySession->socket().receiveBytes(NULL,0) == 0)) {
    mySession->reset();
}

来自 Poco 文档:

bool poll(const Poco::Timespan& timeout, int mode) const;
    /// Determines the status of the socket, using a 
    /// call to select().
    /// 
    /// The mode argument is constructed by combining the values
    /// of the SelectMode enumeration.
    ///
    /// Returns true if the next operation corresponding to
    /// mode will not block, false otherwise.

int receiveBytes(void* buffer, int length, int flags = 0);
    /// Receives data from the socket and stores it
    /// in buffer. Up to length bytes are received.
    ///
    /// Returns the number of bytes received. 
    /// A return value of 0 means a graceful shutdown 
    /// of the connection from the peer.
    ///
    /// Throws a TimeoutException if a receive timeout has
    /// been set and nothing is received within that interval.
    /// Throws a NetException (or a subclass) in case of other errors.

如果您有一个打开的可读套接字,则具有 select_read 模式的 poll 方法将返回 true。 使用 receiveBytes 读取服务器端正常关闭,然后为下一个请求重置套接字。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 2018-02-14
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多