12

玩转KCP(2)-流模式和消息模式

 4 years ago
source link: http://vearne.cc/archives/39322
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | http://vearne.cc

1. 前言

KCP协议包含了2中模式,消息模式和流模式。今天笔者来讲讲这2中模式的区别。

2. 流模式和消息模式

回顾一下KCP协议

0               4   5   6       8 (BYTE)
+---------------+---+---+-------+
|     conv      |cmd|frg|  wnd  |
+---------------+---+---+-------+   8
|     ts        |     sn        |
+---------------+---------------+  16
|     una       |     len       |
+---------------+---------------+  24
|                               |
|        DATA (optional)        |
|                               |
+-------------------------------+

frg :分片,用户数据可能会被分成多个KCP包,发送出去

xtaci/kcp-go 的消息模式实现不完整,这个字段始终为0 详见 issues/121

sn : 序列号

len :数据长度(DATA的长度)

data :用户数据

2.1 消息模式

假定一个场景,在IM中,A向B发送了一个消息,这个消息可能是文本消息,也可能是图片消息。那么应用程序发送的数据是有逻辑的 消息 的概念的。

kCP协议提供了一种能力把不同的 消息 (应用程序)划分在不同的KCP包中。

KCP定义 MSS 的默认大小为1400 bytes, MSS (maximum segment size)表示最大段大小,它本身是TCP中的概念,表示包含TCP header,整个数据包的最大大小。在KCP协议中,概念类似,表示包含KCP header在内,整个KCP包的最大大小。

超过 MSS 的数据将会被拆分到成多个KCP包。根据是否拆包将会分成2种情况。

1)不拆包

IJzumqZ.jpg!web 3条消息 Msg1 , Msg2 , Msg3 分别包含在 sn 为 90、91、92的KCP包中

2) 拆包

假定这个消息是个图片消息,比较大,大小为3252 bytes

2QNfEbV.jpg!web

Msg被拆成了3部分,包含在3个KCP包中。 注意 , frg 的序号是从大到小的,一直到0为止。这样接收端收到KCP包时,只有拿到 frg 为0的包,才会进行组装并交付给上层应用程序。由于 frg 在header中占1个字节,也就是最大能支持

(1400 – 24) * 256 / 1024 = 344kB的消息

总结

在消息模式下,每个KCP包最多包含一个上层应用的消息。

2.2 流模式

消息模式减少了上层应用从流中拆解出消息的麻烦,但是它对网络的利用率较低。Payload(有效载荷)少,KCP头占比过大。

zQRjqmn.jpg!web

在流模式下,KCP试图让每个KCP包尽可能装满。一个KCP包中可能包含多个 消息 。在上图中, Msg1Msg2Msg3 的一部分被包含在 sn 为234的KCP包中。 上层应用需要自己来判断每个消息的边界。

xtaci/kcp-go 中可以通过

var sess *kcp.UDPSession
sess.SetStreamMode(true)

开启流模式

请我喝瓶饮料

ZzaQjmz.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK