You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Winsock2环境下SSL_read在HTTP服务器停止发送数据后阻塞的问题求助

Winsock2环境下SSL_read在HTTP服务器停止发送数据后阻塞的问题求助

各位大佬好,我最近在基于Winsock2开发HTTPS客户端时遇到了一个头疼的问题:当HTTP服务器已经发送完所有响应数据后,SSL_read函数会一直阻塞等待,明明服务器已经没有数据再发了,但它就是停不下来。

我试过用OpenSSL默认的错误处理机制去排查,但因为根本没有错误抛出,所以完全找不到头绪;也尝试把套接字设置为非阻塞模式,但这对SSL套接字似乎不起作用,翻了一圈网上资料也没找到针对性的解决方案。

下面是出现问题的核心代码段:

do {
    bytesRead = SSL_read(ssl, buffer, sizeof(buffer) - 1);
    buffer[bytesRead] = '\0';
    printf("%s\n", buffer);
    sscanf_s(buffer, "HTTP/1.%*d %d", &statusCode);
} while (bytesRead > 0);

这是我完整的代码(做了少量编辑):

int xxx() {
    WSADATA wsaData;
    SSL_CTX* sslContext = NULL;
    char* httpRequest = "just the request, not important";

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("Failed to initialize Winsock.\n");
        return -1;
    }

    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
    sslContext = SSL_CTX_new(TLS_client_method());

    SOCKET socketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (socketClient == INVALID_SOCKET) {
        printf("Failed to create socket.\n");
        closesocket(socketClient);
        WSACleanup();
        return -1;
    }

    struct addrinfo* result = NULL;
    if (getaddrinfo("example.com", "https", NULL, &result) != 0) {
        printf("Failed to resolve hostname.\n");
        closesocket(socketClient);
        WSACleanup();
        return -1;
    }

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = ((struct sockaddr_in*)result->ai_addr)->sin_addr.s_addr;
    serverAddr.sin_port = htons(443);
    freeaddrinfo(result);

    if (connect(socketClient, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        printf("Failed to connect to server.\n");
        closesocket(socketClient);
        WSACleanup();
        return -1;
    }

    SSL* ssl = SSL_new(sslContext);
    SSL_set_fd(ssl, socketClient);
    if (SSL_connect(ssl) != 1) {
        printf("SSL handshake failed.\n");
        SSL_free(ssl);
        closesocket(socketClient);
        WSACleanup();
        return -1;
    }

    if (SSL_write(ssl, httpRequest, strlen(httpRequest)) <= 0) {
        printf("Failed to send HTTP request.\n");
        SSL_free(ssl);
        closesocket(socketClient);
        WSACleanup();
        return -1;
    }

    char buffer[4096];
    int bytesRead = 0;
    int statusCode = 0;

    do {
        bytesRead = SSL_read(ssl, buffer, sizeof(buffer) - 1);
        buffer[bytesRead] = '\0';
        printf("%s\n", buffer);
        sscanf_s(buffer, "HTTP/1.%*d %d", &statusCode);
    } while (bytesRead > 0);

    SSL_shutdown(ssl);
    SSL_free(ssl);
    closesocket(socketClient);
    WSACleanup();
}

我猜测问题可能出在HTTP响应的结束判断上,毕竟HTTP是基于TCP流协议的,SSL_read本身不知道什么时候是响应的结尾,但我实在搞不清楚该怎么在SSL层正确处理这种情况,希望有经验的朋友能给我指点一下,谢谢大家!

备注:内容来源于stack exchange,提问作者xax321

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 08:38:02