当前位置:   article > 正文

一种tcp传输json包时出现包不完整、粘包的解决方案_tcp发送json报文

tcp发送json报文

1.场景介绍

较大的json包在tcp发送时会分成多个包,接收端比较难判断包的完整性,和是否存在包粘连的问题

json包不完整包存在粘连
{"id":"001","name":"jsonPick"}{"id":"001","name":"jsonPick"}{"id":"001","name":"jsonPick"}

2.解决方案

  1. 用正则表达式来验证json格式是否完整
  2. 验证不完整时,等待并拼接下个包直到完整为止
  3. 当存在粘包时,用正则表达式的方案提取完整包
  4. 当存在多个完整包时,用正则表达式的方案提取多个完整包

下表为一个完整的json包、正则表达式和运行结果

json内容{"id":"001","name":"jsonPick"}
正则表达式\s*\{\s*"\w*\"\s*:\s*"\w*\"\s*,\s*"\w*\"\s*:\s*"\w*\"\s*\}\s*
运行结果

begin: 0

0 : "{\"id\":\"001\",\"name\":\"jsonPick\"}"

3.解决方案的多场景模拟

1.包不完整

json内容{"id":"001","name":"json
正则表达式\s*\{\s*"\w*\"\s*:\s*"\w*\"\s*,\s*"\w*\"\s*:\s*"\w*\"\s*\}\s*
运行结果

begin: -1

0 : ""

2.完整包,前粘连

json内容e":"jsonPick"}{"id":"001","name":"jsonPick"}
正则表达式\s*\{\s*"\w*\"\s*:\s*"\w*\"\s*,\s*"\w*\"\s*:\s*"\w*\"\s*\}\s*
运行结果

begin: 14

0 : "{\"id\":\"001\",\"name\":\"jsonPick\"}"

3.完整包,后粘连

json内容{"id":"001","name":"jsonPick"}{"id":"001","name":
正则表达式\s*\{\s*"\w*\"\s*:\s*"\w*\"\s*,\s*"\w*\"\s*:\s*"\w*\"\s*\}\s*
运行结果

begin: 0

0 : "{\"id\":\"001\",\"name\":\"jsonPick\"}"

4.完整包,前后粘连

json内容e":"jsonPick"}{"id":"001","name":"jsonPick"}{"id":"001","name":
正则表达式\s*\{\s*"\w*\"\s*:\s*"\w*\"\s*,\s*"\w*\"\s*:\s*"\w*\"\s*\}\s*
运行结果

begin: 14

0 : "{\"id\":\"001\",\"name\":\"jsonPick\"}"

5.包中包

json内容{
    "id": "001",
    "name": "{\"id\":\"001\",\"name\":\"jsonPick\"}"
}
正则表达式\s*\{\s*"\w*\"\s*:\s*"\w*\"\s*,\s*"\w*\"\s*:\s*"\w*\"\s*\}\s*
运行结果

begin: -1

0 : ""

限制于\w=Matches a word character (QChar::isLetterOrNumber(), QChar::isMark(), or '_').

\w无法匹配"、{、}等字符,故无法处理包中包的情况

4.总结

1.正则表达式能有效的判断包的完整性

2.正则表达式能在有粘包的前提下提取到完整的包

3.不支持包中包

附源码

  1. /**
  2. * \s 表示一个\t、一个\n等
  3. * \s Matches a whitespace character (QChar::isSpace()).
  4. * \s* 多个
  5. * \s+ 至少一个
  6. * \s{2} 两个
  7. * \s{1,2} 一个到两个
  8. * \w 表示一个字母、一个数字、一个汉字等
  9. * \w Matches a word character (QChar::isLetterOrNumber(), QChar::isMark(), or '_').
  10. * \w* 多个
  11. * \w+ 至少一个
  12. * \w{2} 两个
  13. * \w{1,2} 一个到两个
  14. * () 表示提取的位置
  15. */
  16. QString Output = R"(
  17. {
  18. "id": "001",
  19. "name": "jsonPick"
  20. }
  21. )";
  22. QRegExp rx(R"(\s*\{\s*"\w*\"\s*:\s*"\w*\"\s*,\s*"\w*\"\s*:\s*"\w*\"\s*\}\s*)");
  23. qDebug() << "begin:" << rx.indexIn(Output);
  24. QStringList qsl = rx.capturedTexts();
  25. for(int i = 0; i < qsl.count(); i++)
  26. {
  27. qDebug() << i << ": " << qsl.at(i);
  28. }
  29. return 1;

运行结果

begin: 0

0 : "\n {\n \"id\": \"001\",\n \"name\": \"jsonPick\"\n }\n "

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/522939
推荐阅读
相关标签
  

闽ICP备14008679号