客户端偶现没有收到服务器响应问题的排查
客户端偶现没有收到服务器响应问题的排查
- 问题描述
- 问题排查
- 总结
问题描述
客户端偶现收不到服务器端返回的响应包。
问题排查
当出现服务器端收不到客户端的请求包,或者客户端收不到服务器端的响应包时,第一反应就是是抓包,先确定是否存在丢包的可能。
输入命令:tcpdump -i eth0 src port 9983 -XX
抓取我们服务器9983端口发出去的包,结果如下:
其中红色圈出来的部分就是应该返回的响应包,确定服务器端没有丢包。同样的,使用wireshark抓来自服务器端的包,结果如下:
客户端也收到了服务端的包,到此基本排除丢包的可能。
这个时候我同时也注意到了XWGetKpacgRSp这个响应包是和上一个响应包未发完的部分作为一个完整包发送的。上一个响应包大小是2720字节:
当前包大小是527字节:
因此推测是不是客户端处理拆包的流程有问题,贴上客户端处理拆包的代码:
for (;;){//初始化为0,分配四分之一的READ_BUF_SIZE大小,约为32768字节uint32_t free_buf_len = m_in_buf.GetAllocSize() - m_in_buf.GetWriteOffset();if (free_buf_len < READ_BUF_SIZE)m_in_buf.Extend(READ_BUF_SIZE);int ret = netlib_recv(m_handle, m_in_buf.GetBuffer() + m_in_buf.GetWriteOffset(), READ_BUF_SIZE);if (ret <= 0) break;//write_offset偏移当前已经接收的字节数m_in_buf.IncWriteOffset(ret);//做最小长度保护while (m_in_buf.GetWriteOffset() >= imcore::HEADER_LENGTH){//比如接收到了472+55字节//其中472字节和前面的27200是一起的,且length=27668//第一次取出来的是上面netlib_recv返回的长度uint32_t len = m_in_buf.GetWriteOffset();uint32_t length = 0;//获取包体长度memcpy(&length, m_in_buf.GetBuffer(), sizeof(length));length = ntohl(length);//len:接收的总长度//length:包体长度//PACK_HEADER_LENGTH:包体长度的长度//PACK_HEADER_LENGTH + length <= len : 才可以解析//如果字符串长度大于此次接收的长度,那么不处理,等待下一次if (length + PACK_HEADER_LENGTH > len)break;try{if (m_pTcpSocketCB)m_pTcpSocketCB->onReceiveData((const char*)m_in_buf.GetBuffer(), length + PACK_HEADER_LENGTH);LOGBIN_F__(SOCK, "OnRead", m_in_buf.GetBuffer(), length + PACK_HEADER_LENGTH);}catch (std::exception& ex){assert(FALSE);LOGA__(NET, "std::exception,info:%s", ex.what());if (m_pTcpSocketCB)m_pTcpSocketCB->onReceiveError();}catch (...){assert(FALSE);LOG__(NET, _T("unknown exception"));if (m_pTcpSocketCB)m_pTcpSocketCB->onReceiveError();}//已经读取的长度置为已读m_in_buf.Read(NULL, len);}}
XWGetKpacgRSp上一个响应包的大小为4+27668字节,每次发送2720字节,总共发送了10次,最后一个包527字节。也即最后一个网络包包含了55字节大小的XWGetKpacgRSp响应包(因为TCP协议是流模式的)。
那么在这段代码中,需要判断包体长度和接收长度的大小,如果接收长度小于包体长度,那么不做处理,继续接收,直到接收长度大于等于包体长度。最后将接收到的长度置为已读,避免下次再读:
//已经读取的长度置为已读
m_in_buf.Read(NULL, len);
可是这里置为已读的长度是当前接收缓存中的未读内容的总长度(也就是上面的2720*10+527),也就是将55字节大小的XWGetKpacgRSp响应包合并到了上一个响应包,这样就导致拆包失败,客户端没有再对XWGetKpacgRSp响应包做处理。将代码修改如下解决问题:
//已经读取的长度置为已读
m_in_buf.Read(NULL, length + PACK_HEADER_LENGTH);
总结
客户端对服务端的数据包进行处理时,需要考虑粘包问题,这一点大家都知道,那么在书写代码的时候就需要格外小心,避免因为低级的代码书写错误导致程序功能异常。
当出现客户端与服务器端收不到对方的请求或响应时,按照以下流程排查问题:
1,抓包。分别抓客户端和服务端的网络数据包,看数据是否发送出去或者接收到。(TCP协议是可靠的,不存在丢包问题)
2,如果服务端没有发出响应包,则排查服务端的发包流程是否正常。
3,如果服务端有发出数据包,客户端也有收到,那么排查客户端的收包流程是否正常,特别是粘包,拆包的处理。
客户端偶现没有收到服务器响应问题的排查相关推荐
- 谷歌邮箱服务器验证失败,Gmail错误:SMTP服务器需要安全连接,或者客户端未经身份验证。服务器响应为...
Gmail错误:SMTP服务器需要安全连接,或者客户端未经身份验证.服务器响应为 我使用以下代码发送电子邮件.代码在我的本地机器中正确工作.但是在生产服务器上,我得到了错误消息.var fromAdd ...
- 服务器流式响应,HttpClient在收到服务器响应后无法停止流式传输
我一直在使用.NET 4.5中的HttpClient挣扎了一段时间.在通过分块传输对WebApi端点进行大型流式上传时,如果服务器已通过非成功状态代码(未找到,认证,授权,验证错误等)响应中间请求,则 ...
- inode客户端未收到服务器响应,iNode认证通过后提示“未收到服务器相应,即将强制下线的解决办法”...
iNode认证提示服务器无响应 一,问题描述 使用iNode客户端进行portal或者8021x认证,身份认证通过后过了十几秒,iNode提示"未收到服务器相应,即将强制下线",然 ...
- 东方梦符祭未能收到服务器响应,东方梦符祭loading不进去 常见问题解决办法
最近东方梦符祭更新之后不少玩家反应出现Loading进不去游戏的情况,遇到这样的问题,大家可以参考以下的解决方法. 推荐阅读[东方梦符祭新手N1 进阶攻略 东方梦符祭要怎么玩] >>> ...
- 并发请求多 服务器响应慢 post,【转】吞吐量、QPS(TPS)、并发数、RT性能指标及ab并发测试...
概念 吞吐量 系统的吞吐量是指系统的抗压.负载能力,指的是单位时间内处理的请求数量.通常情况下,吞吐率用 "字节数/秒" 来衡量,也可以用 "请求数/秒",&q ...
- 服务器响应回调函数,解决有关flask-socketio中服务端和客户端回调函数callback参数的问题(全网最全)...
由于工作当中需要用的flask_socketio,所以自己学习了一下如何使用,查阅了有关文档,当看到回调函数callback的时候,发现文档里都描述的不太清楚,最后终于琢磨出来了,分享给有需要的朋友 ...
- 网页现现实理服务器没有响应,前端_网页编程 HTTP协议(进阶)
文章目录 内容 1. HTTP协议简介 1.1 什么是通信 1.1.1 现实生活中的通信 1.1.2 互联网中的通信 1.2 什么是通信协议 1.2.1 现实生活中的通信协议 1.2.2 互联网中的通 ...
- 服务器响应到客户端中文乱码的解决方式
服务器与客户端交互的过程中出现中文乱码的解决方式 服务器响应到客户端中文乱码的解决方式 在Java Web开发的过程中,很多人都会遇到当服务器向浏览器发送响应页面时,有时候因为码表的查询不一致,会在浏 ...
- inode显示未收到服务器回应,inode智能客户端 未收到服务器回应
inode智能客户端 未收到服务器回应 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云 ...
最新文章
- R语言dplyr包if_else条件判断选择函数实战
- 多行文本框限制输入字符长度(两种方法)
- iOS Sprite Kit教程之xcode安装以及苹果帐号绑定
- data中的数据如何在innerhtml中调用_Vuex中调用state数据
- batocera游戏整合包_星露谷物语绅士mod整合包
- 使用DynamoDBMapper扫描DynamoDB项目
- 不使用Ajax,如何实现表单提交不刷新页面
- vue按钮Button
- Go 远超 Python,机器学习人才极度稀缺,全球 16,655 位程序员告诉你这些真相!...
- 家装计算器php,家装计算器
- [转载] python数字类型(一)
- 读写分离无效的大坑(新使用数据库读写分离的同学可以参考)
- 贝叶斯(Bayes)决策理论
- MacBook重装系统
- python实现CRAPS赌博游戏。
- b站《史上最全unity3D教程》2-6等ppt笔记3
- UiPath估值超百亿!这家来自罗马尼亚深耕中国市场的公司已进入市场高增长期...
- 课程linux实验报告,Linux课程综合训练实验报告
- 部门换届推文文字_毕业季,换届忙
- mp3剪切器如何剪切mp3格式的音频