如何用QTcpSocket实现HTTP请求?解决400 Bad Request问题
解决HTTP 400错误的方案
你的代码核心问题是多发送了一段HTTP协议不需要的长度前缀。HTTP是基于文本的应用层协议,请求报文直接以明文形式发送即可,不需要先传递报文长度。你调用IntToArray生成的4字节二进制数据会被服务器当作请求的起始部分,导致整个请求格式完全不符合HTTP规范,所以返回400错误。
修正步骤
- 直接删除
socket->write(IntToArray(dataToSendToServer.size()));这一行代码,只发送HTTP请求文本内容。 - 可选优化:将HTTP版本升级为1.1(大部分服务器对1.1支持更好),同时确保请求路径格式正确。
修正后的核心代码
this->socket = new QTcpSocket(this); this->socket->connectToHost(QHostAddress("172.64.155.249"), 80); // stackoverflow.com if (!this->socket->waitForConnected()) { qDebug() << this->socket->errorString(); exit(1); } // 改用HTTP/1.1,保持请求格式合规 auto dataToSendToServer = QString("GET /questions HTTP/1.1\r\nHost: stackoverflow.com\r\nConnection: close\r\n\r\n"); socket->write(dataToSendToServer.toUtf8()); // 直接发送请求文本,去掉多余的长度前缀 if (!socket->waitForBytesWritten()) { qDebug() << this->socket->errorString(); exit(2); } connect(socket, &QIODevice::readyRead, this, [&](){ auto receivedData = socket->readAll(); qDebug() << QString(receivedData); });
补充说明
- HTTP协议要求请求头末尾必须有两个连续的
\r\n,用来分隔请求头和请求体(GET请求没有请求体,所以这两个换行就是请求的结束标志),你的原代码里这部分是正确的。 - 如果后续需要发送带请求体的POST请求,只需在请求头中添加
Content-Length字段指定体内容长度即可,不需要提前发送二进制长度前缀。
内容的提问来源于stack exchange,提问作者Roman Podymov
相关产品推荐
相关产品推荐

