首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于TCP网络通信

关于TCP网络通信

作者头像
后端技术探索
发布2018-08-09 16:33:03
7820
发布2018-08-09 16:33:03
举报
文章被收录于专栏:后端技术探索后端技术探索

作者:Rango韩天峰

原文:http://rango.swoole.com/archives/464

TCP协议在底层机制上解决了UDP协议的顺序和丢包重传问题。但相比UDP又带来了新的问题,TCP协议是流式的,数据包没有边界。应用程序使用TCP通信就会面临这些难题。一些程序在本机测试是正确的,上线后就出现各种奇怪的BUG。如下面的伪代码,客户端向服务器端发送一个json字符串,服务器端接收此字符串。在慢速网络中Server无法正确接收完整的JSON字符串。

$client->send(json_encode('a' => $data_10k, 'b' => $data_5k));
$pkg = $server->recv(); //Server收到的数据只有一小部分

$client->send("hello1");
$client->send("hello2");
$client->send("hello3");
$pkg = $server->recv(); //Server会一次性收到3个数据包

因为TCP通信是流式的,在接收1个大数据包时,可能会被拆分成多个数据包发送。多次Send底层也可能会合并成一次进行发送。这里就需要2个操作来解决:

  • 分包:Server收到了多个数据包,需要拆分数据包
  • 合包:Server收到的数据只是包的一部分,需要缓存数据,合并成完整的包

具体编码实现这里就不讲了,这是一个比较复杂的编程过程,稍有不慎就会出现严重的BUG

Swoole如何解决此问题

swoole提供了通用协议的支持,如Http和WebSocket。自定义协议可以使用Length/EOF 2种协议解析方式来完美解决此问题。从1.7.18版本开始,Swoole的Server/Client都支持了Length/EOF的协议处理方式,应用层代码只需要配置一下参数,就无需关注底层分包合包了。每次onReceive收到的数据包总是完整的。

Server/Client的配置是相同的

Http/WebSocket

swoole内置对http/websocket 2种协议的支持,如果要实现一个http服务或者websocket服务,直接用swoole_http_server和swoole_websocket_server即可。

EOF

$server->set(array('open_eof_split' => true, 'package_eof' => "\r\n"));

EOF协议处理的原理是每个数据包结尾加一串特殊字符表示包已结束。如memcache、ftp、stmp都使用\r\n作为结束符。发送数据时只需要在包末尾增加\r\n即可。使用EOF协议处理,一定要确保数据包中间不会出现EOF,否则会造成分包错误。

Length

$server->set(array(
'open_length_check' => true,
'package_max_length' => 81920,
'package_length_type' => 'n', //see php pack()
'package_length_offset' => 0,
'package_body_offset' => 2,
));

固定包头的协议非常通用,在BAT的服务器程序中经常能看到。这种协议的特点是一个数据包总是由包头+包体2部分组成。包头由一个字段指定了包体或整个包的长度,长度一般是使用2字节/4字节整数来表示。服务器收到包头后,可以根据长度值来精确控制需要再接收多少数据就时完整的数据包。Swoole的配置可以很好的支持这种协议,可以灵活地设置4项参数应对所有情况。

Swoole的Server和异步Client都是在onReceive回调函数中处理数据包,当设置了协议处理后,只有收到一个完整数据包时才会触发onReceive事件。同步客户端在设置了协议处理后,调用 $client->recv() 不再需要传入长度,recv函数在收到完整数据包或发生错误后返回。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-03-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nginx 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Swoole如何解决此问题
    • Http/WebSocket
      • EOF
        • Length
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档