问题1:如何实现?
- pc 端用 Qt 写的,但是 Qt 不带 http server
- 设备端需要http client
解决思路:
- 重复造轮子,自己裸写一个
- 或者引入第三方开源库
最终决定后者,c 语言的关于http 开源库非常多,这里不多介绍。适用于Qt 的http server 前文有提到,使用的是tufao 直接迁移到Qt 中,很方便。
你以为这样就完了,那就没有这篇文章的必要了。
问题2:为什么在进行大数据比如图片或者二进制传输时,会出现接收不全?
经过阅读 tufao 源码并调试,终于让我看到以下说明:当一个http request完成后会发送end 信号。
改正后处理策略如下(参考 sunyongsunyong博客):将请求结构处理放在end 信号关联的槽函数上,这样就能保证数据的完整性。
一切看似ok了,某一天,突然要增加 http 1.1 支持,同时要支持chunked 传输,新的问题又来了。
问题3:为什么 改为http 1.1 后设备端 response 会失败?
- 服务器问题 response 数据格式不对;
- 客户端问题,接收response失败,或者解析失败;
经过调试以及抓包分析发现,Qt 端 http server response 时 http header 带有 chunked 属性,所以body 数据 格式也变了。
接着开始debug 设备端,发现 recv data ok,但是解析失败了。
这个时候问题已经明朗了,传输没有问题,问题出在解析上,在某个环节出问题了,这个时候就不得不怀疑用的库了?
于是乎在研究 http 1.1 chunked 协议传输后,并阅读源码发现,chunked_length计算有误。chunked data 的长度 是以16进制字符串形式写进去的。如图是我修改后的,原来按照10进制计算的(这里猜测是作者笔误)
基本的 http 1.1 传输调通了,不过当我进行 POST 请求 通过chunked 发送时,新的问题又来了?
问题4:我需要自己打包好 chunked 的数据包格式?
对于你个开源库,最理想的情况就是屏敝各种细节,用户只需要输入,输出就行。显然,我用的这个就没有,找到 sample 一看,果然如此。
结合自己研究http 1.1 chunked 的数据包后,自己手动封装了一个数据打包函数,这样通信就ok了。另人欣慰的是上位机的库做的比较好,无需改动,就可兼容http 1.0/1.1的数据接收。
过了一段时间,新的问题又来了。在一台C# 开发上位机上通信失败了。
问题5:http 1.1 为什么会报 400 error ?
经过一番搜索,让我看到以下说明,大致意思是,http 1.1请求必须包含 HOST 信息。
同时通过 postman 验证,去掉和加上HOST 测试发现果真如此。于是加上 HOST ip 和端口号就ok了。
有一点没想通的是,不知道为何,Qt 上面没有加也通信ok?
总结:
- 需不需要重复造轮子?我觉得要有造轮子的能力,但是不一定要造;
- 要有研究精神,敢于去看源码,不能只停留在会用层面,这样遇到问题就会退缩;
- 要大胆怀疑,就算是大神写的东西也有可能疏忽,源码不一定都是对的;
- 适当的时候还是需要了解技术细节的,小小的调试,暴露太多问题,技术细节只有在遇到困难是才能体现出来;
- 第三方库做的越优秀,对技术细节屏蔽越厉害,你上手就越快,但是弊端也很明显,时间久了,出问题了自己就不知道如何解决。
- 比较喜欢Linus Torvalds 的 一句名言:Read The Fucking Source Code(RTFSC),大不了阅读源码罢了
参考链接:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
https://blog.csdn.net/sunyongsunyong/article/details/79308882