基于SSL TCP/IP的自定义实时JSON协议测试及参数问题求助
问题分析与解决方案
核心问题
你用的Postman、curl都是HTTP客户端工具,但目标服务是基于SSL/TCP的自定义文本协议,并非HTTP协议,工具的HTTP逻辑会和服务器协议不兼容,因此触发报错。
正确测试方法
1. 使用SSL TCP直接连接工具
放弃HTTP客户端,改用能直接建立SSL TCP连接并发送自定义文本的工具,比如openssl s_client或带SSL支持的ncat:
方法一:openssl s_client(通用方案)
先建立连接:
openssl s_client -connect eu.xxxxxxxxxx.com:11001 -quiet
连接成功后,手动输入符合格式的命令(注意密码中的%在终端需要转义为\%):
LOGIN:100::{"user":"XXXXXXX","password":"xxxx\%xxxx","app":"ManualTest","app_ver":"1.0.0","protocol":"CustomProtocolABCD","protocol_ver":"1.0.0"}
如果服务器严格要求\r\n结尾,用echo -e生成转义字符并管道发送:
echo -e 'LOGIN:100::{"user":"XXXXXXX","password":"xxxx\%xxxx","app":"ManualTest","app_ver":"1.0.0","protocol":"CustomProtocolABCD","protocol_ver":"1.0.0"}\r\n' | openssl s_client -connect eu.xxxxxxxxxx.com:11001 -quiet
方法二:ncat(若已安装)
ncat --ssl eu.xxxxxxxxxx.com 11001
连接后输入上述格式的命令即可。
2. 修正命令格式
服务器返回Wrong number of parameters,是因为你用curl的-d参数拆分了命令字段,但协议要求所有字段必须拼接成单行命令,格式为:
[command-id]:[message-id]:[channel]:[data]\r\n
你的LOGIN命令中channel字段为空(对应::),所以正确的单行命令就是上面示例的格式。
3. 密码中的%符号处理
- 在终端输入时,
%是shell特殊字符(用于变量替换),必须转义为\%; - 在代码(比如Qt)中,直接将
%作为字符串的一部分放入JSON即可,无需额外转义(JSON本身不对%做特殊处理)。
Qt嵌入式开发实现思路
用Qt的QSslSocket实现通信,步骤如下:
- 初始化SSL套接字并连接服务器:
QSslSocket *socket = new QSslSocket(this); socket->connectToHostEncrypted("eu.xxxxxxxxxx.com", 11001);
- 连接成功后发送LOGIN命令:
connect(socket, &QSslSocket::encrypted, [socket]() { QString loginCmd = QString("LOGIN:100::%1\r\n").arg( QString(R"({"user":"XXXXXXX","password":"xxxx%xxxx","app":"ManualTest","app_ver":"1.0.0","protocol":"CustomProtocolABCD","protocol_ver":"1.0.0"})") ); socket->write(loginCmd.toUtf8()); });
- 监听响应并解析JSON:
connect(socket, &QSslSocket::readyRead, [socket]() { QByteArray response = socket->readAll(); // 按\r\n分割响应行,处理每条数据 QStringList lines = QString(response).split("\r\n", Qt::SkipEmptyParts); for (const QString &line : lines) { QJsonDocument doc = QJsonDocument::fromJson(line.toUtf8()); qDebug() << "Response:" << doc; } });
- 处理SSL错误与连接异常:
connect(socket, QOverload<const QList<QSslError>&>::of(&QSslSocket::sslErrors), [socket](const QList<QSslError> &errors) { // 忽略自签名证书(若服务器使用自签证书) socket->ignoreSslErrors(errors); }); connect(socket, &QSslSocket::disconnected, [socket]() { qDebug() << "Disconnected from server"; });
相关协议参考
这类协议属于自定义SSL/TCP文本协议,没有通用标准文档,核心遵循以下要点:
- 基于行的通信:每条命令/响应以
\r\n结尾; - 命令格式严格遵循
command-id:[message-id[+]]:[channel]:[data]; - 数据部分为JSON格式,按JSON规则解析即可。
可重点参考Qt官方文档中QSslSocket的使用说明,以及TCP套接字通信基础教程,重点关注行分隔数据的处理(避免粘包问题)和SSL握手流程。
内容的提问来源于stack exchange,提问作者boxitracio
相关产品推荐
相关产品推荐

