gpt4 book ai didi

c++ - SSL_write 报告成功但在 Safari 中失败

转载 作者:行者123 更新时间:2023-11-30 03:43:18 31 4
gpt4 key购买 nike

我自己实现了一个使用 openssl 的网络服务器。

我在 OSX 上使用 SSL_write 的阻塞版本传输数据和最新的 Safari。

我的逻辑是这样的:

num_bytes = 0;
while( num_bytes < bytes_to_send) {
int n = SSL_write(...);
if (n <= 0) {
... // Handle error, break loop
}
num_bytes += n;
}
// Close the socket

我遇到一个不常见的问题,Safari 报告加载资源失败:网络连接丢失。

当我在 Safari 下的开发人员面板中检查资源时,它显示接收到的字节数少于预期。

我已经调试了我的代码并确定 SSL_write 正在报告在我关闭连接之前所有字节都已传输。

当我不关闭连接时,此错误不再出现。

这使我得出以下结论:

SSL_write 错误地报告了在实际发生之前已成功传输的字节数,并且在缩短传输时间后立即关闭连接。

我说的对吗,还是我遗漏了有关 SSL_write 的详细信息?

更新:

在检查了我处理 SSL_shutdown 的方式后,我看到报告了几个 SSL_ERROR_SYSCALL 错误。这可能与我的问题有任何关系,也可能没有任何关系,因为这些错误不会在受影响的 http 传输后直接返回。奇怪的是,在受影响的 http 传输期间,SSL_shutdown 除了阻止调用的重试错误之外没有报告任何错误。

关机代码

// First shutdown SSL
SSL_CTX_free(ctx);
if (SSL_shutdown(ssl) == 0) {
// Call SSL Shutdown again
SSL_shutdown(ssl);
}
SSL_free(ssl);

// Now shutdown port
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 10;
setsockopt(socket, SOL_SOCKET, SO_LINGER, (char *)&linger,
sizeof(linger));

shutdown(socket, SHUT_WR);
while(recv(...) > 0) { }
closesocket(socket);

更新#2

我设置了带有 ssl 解密的 wireshark 来捕获错误。这是它的样子: Safari Error Message: PatientSearch.js Wireshark Capture: See PatientSearch.js Successfully Transferred

注意第一条绿线,它显示了来自 Safari 的 PatientSearch.js 的 HTTP 请求。现在第二条绿线显示了来 self 的网络服务器的 HTTP 响应。此响应包含整个文件,后跟断开连接协议(protocol)。

更新 #3

这越来越神秘了。在检查成功传输的 wireshark 跟踪后,成功传输与中断传输的协议(protocol)模式没有区别。现在完全糊涂了。

最佳答案

您的发送循环没有正确跟踪发送的字节数。它应该看起来更像这样:

unsigned char *data = ...;
while (bytes_to_send > 0) {
int num_sent = SSL_write(ssl, data, bytes_to_send);
if (num_sent <= 0) {
// handle error as needed...
break;
}
data += num_sent;
bytes_to_send -= num_sent;
}
// Close the socket

或者这个:

unsigned char *data = ...;
int num_total_sent = 0;
while (num_total_sent < bytes_to_send) {
int num_sent = SSL_write(ssl, &data[num_total_sent], bytes_to_send - num_total_sent);
if (num_sent <= 0) {
// handle error as needed...
break;
}
num_total_sent += num_sent;
}
// Close the socket

更新:

SSL_write incorrectly reports a number of bytes were successfully transferred before it has actually occurred

返回值报告它从您那里接受的字节数。这并不能保证这些字节实际上已经传输了。它们被加密并用于创建传出 SSL 帧,该帧位于底层套接字的出站缓冲区中,等待内核在后台实际传输它。该传输可能需要一些时间,特别是如果在套接字上启用了 Nagle 算法(通常默认情况下)。

closing the connection immediately after cuts the transfer short.

这是可能的,具体取决于您关闭连接的方式、套接字的延迟选项的配置方式等。默认情况下,优雅地关闭套接字应该允许内核在后台花费一些额外的时间来写出任何在它之前等待数据然后实际关闭连接。您通常必须采取额外措施来改变这种行为。

关于c++ - SSL_write 报告成功但在 Safari 中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36207378/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com