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

为何SSL_read会陷入无限循环?Python服务端与C客户端通信异常

问题原因及解决办法

核心问题:服务端与客户端通信协议不匹配

你的Python服务端使用普通TCP套接字,但C客户端却用SSL加密套接字通信,两者协议完全不兼容:

  • 客户端通过SSL_write发送的是加密后的数据,服务端直接用recv读取明文,你看到服务端收到Hello world的情况不符合逻辑(大概率是SSL_connect实际失败,但客户端没检查返回值,SSL_write意外退化为明文发送)。
  • 反过来,服务端用send发送明文,客户端用SSL_read读取,后者期望的是SSL加密数据包,自然会一直阻塞等待合法的SSL数据。

解决方向一:服务端启用SSL

修改Python服务端,让它支持SSL通信:

import socketserver
import ssl

class SSLConnectionHandler(socketserver.BaseRequestHandler):
    def handle(self):
        # 将普通socket包装为SSL socket
        ssl_socket = ssl.wrap_socket(
            self.request, 
            server_side=True, 
            certfile="server.crt", 
            keyfile="server.key"
        )
        try:
            tmp = ssl_socket.recv(4096).strip().decode("utf8")
            ssl_socket.send("this is the server\n".encode("utf8"))
        finally:
            ssl_socket.close()

if __name__ == "__main__":
    server = socketserver.TCPServer(("127.0.0.1", 10001), SSLConnectionHandler)
    server.serve_forever()

提前用OpenSSL生成SSL证书和密钥:

openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes

解决方向二:客户端改用普通TCP套接字

如果不需要加密,去掉客户端的SSL逻辑,直接用普通socket通信:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(){
    int socfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(10001);
    inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);

    // 直接建立普通TCP连接
    connect(socfd, (struct sockaddr*)&server_addr, sizeof(server_addr));

    // 发送消息
    char text[] = "Hello world";
    send(socfd, text, sizeof(text), 0);
    
    // 读取服务器消息
    char buffer[10];
    ssize_t bytes_read = recv(socfd, buffer, sizeof(buffer)-1, 0);
    if (bytes_read > 0) {
        buffer[bytes_read] = '\0'; // 手动添加字符串结束符,避免乱码
        printf("Server replied: [%s]\n", buffer);
    }
    close(socfd);
    return 0;
}

额外注意事项

  • 服务端发送后关闭连接:发送完数据后关闭套接字,让客户端感知数据传输结束,避免持续阻塞。
  • 检查函数返回值:客户端要检查SSL_connect、SSL_write、SSL_read或普通connect、send、recv的返回值,出错时及时处理,比如SSL_connect返回1才表示握手成功,失败时用SSL_get_error排查问题。
  • 字符串结束符处理:客户端的buffer不会自动添加\0,读取后手动补充,否则printf会输出乱码。

内容的提问来源于stack exchange,提问作者loaded_dypper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:01:17