直接说明下我遇到的问题吧,客户端发送http协议,服务器是Qt写的,用QTcpSocket直接解析,如下HTTP
POST http://192.1.xxx.xxx:18888/XXXXX HTTP/1.1
Content-Type: application/json;charset=UTF-8
User-Agent: Java/1.8.0_181
Host: 192.1.101.189:18888
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 99999
{"xxxx":xxx,"xxx":"xxx","xxx":"xxx"}
这里使用的是Java的RestTemplate。
服务端是这样调用的
if(tcpSocket->waitForReadyRead(10 * 1000)){
QString msg = QString::fromUtf8(tcpSocket->readAll());
......
......
......
}
这样问题就来了,差不多每5次,就有1次,msg会收到:
POST http://192.1.xxx.xxx:18888/XXXXX HTTP/1.1
Content-Type: application/json;charset=UTF-8
User-Agent: Java/1.8.0_181
Host: 192.1.101.189:18888
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 99999
没有body部分,这就坑了。
后面通过抓包(这里要用wireshark,使用Fiddler等web抓包是看不到现象的)等一系列测试。Java中RestTemplate这个类,有时会把http包拆分成两个(postman和一些tcp调试工具不会)。先发header以及最后的\r\n。再发body。
注意:这里经过大量测试不管你的数据包是多大还是多小,比如就200字节的数据包,他也会差分成2个包发,10000字节的数据,他有时只会发1个包(这里只指应用层,不讨论网卡里面的MTU和路由器包分组)。所以这里应该算是一个RestTemplate的坑。Get方法正常。
并且这个body的大小(UTF-8编码)等于Content-Length,这个是http协议规定的。所以面对这样的情况,得修改下post方法的解析。增加这样的内容:
int contentLength = DataAnaylsisTool::getHttpHeaderValue(msg, "Content-Length").toInt();
QString body = DataAnaylsisTool::getHttpBody(msg);
while(body.size() != contentLength){
tcpSocket->waitForReadyRead();
qint64 available = tcpSocket->bytesAvailable();
QString bodyMsg = tcpSocket->read(available);
body += bodyMsg;
}
这个getHttpHeaderValue获取了Content-Length的大小。
这个getHttpBody获取了body的内容。
通过这种方式,不管他body里面分了多少个包,都可以获取到。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://it1995.blog.csdn.net/article/details/121925409
内容来源于网络,如有侵权,请联系作者删除!