Skip to content

Cooperate With Tcp Server

Jim edited this page Jun 15, 2021 · 12 revisions

在使用 KCP时,你可以用在你 TCP的基础上,在登陆时服务端返回 UDP端口和密钥,客户端通过 TCP收到以后,向服务端的 UDP端口每隔一秒重复发送包含握手信息,直到服务端返回成功或者失败。服务端通过 UDP传上来的密钥得知该客户端 sockaddr对应的 TCP连接,这样就建立 TCP连接到 UDP连接的映射关系。为了保持连接和 NAT出口映射,客户端一般需要每 60秒就发送一个 UDP心跳,服务端收到后回复客户端,再在这个 UDP连接的基础上增加调用 KCP的逻辑,实现快速可靠传输,这样一套 TCP/UDP两用的传输系统就建立了。

可以参考下述例子:

  1. 客户端链接tcp,服务端为该tcp链接分配一个整数id作为标识。
  2. 登录后服务端给客户端发送udp握手信息,包括:自己的udp端口,用户的tcp标识id,32位随机数key
  3. 客户端给服务端udp地址发送握手信息,把刚才服务端发过来的(id, key) 发送给服务端。
  4. 服务端确认udp握手,并且记录该用户udp远端地址
  5. 以后客户端和服务端udp通信,每个包都包含(id, key),
  6. 服务端用客户端发上来的(id,key),确认用户身份,并对比远端地址confirm是一个合法用户。

注意:为了保持 NAT映射关系,UDP需要每隔 60秒就向服务器 ping一次。同时为了防止出口地址改变(NAT映射改变,或者移动设备切换基站),可以使用重连,或者UDP重绑定(但是在 3G,2G,EDGE下面,出口改变,TCP也就断了,所以简单重连也没问题)。

客户端和原有的TCP连接对象稍微封装一下,就得到一个类似:

connection.send(channel, data, size)

的接口,channel=0时,使用原有tcp发送,channel=1时使用kcp发送,channel=2时使用裸的udp发送。三个channel同时工作,适配不同情况。服务端接口也类似。

中国的网络情况比较特殊,会存在有些网络 UDP连接不上的情况,因此都是先连接 TCP,然后试图 UDP,UDP不通的情况下,退回 TCP也能正常游戏,一旦 TCP断开,则认为 UDP也断开了。

Clone this wiki locally