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
相关产品推荐
相关产品推荐

