Unity3D网络游戏实战——深入了解TCP,解决暗藏问题
前言
这一章基本属于科普章节,相信看到这篇文章的人也学习过计算机网络,所以很多基础知识,比如三握四挥这些就不多说了。
5.3常用TCP参数
5.3.1ReceiveBufferSize
指定了操作系统读缓冲区的大小,默认值8192。缓冲区满了,发送端会暂停发送数据,较大的缓冲区可以减少发送短暂停的概率,提高效率。
5.3.2SendBufferSize
指定操作系统写缓冲区的大小,默认值也是8192,设定的大一点也比较好~
5.3.3NoDelay
默认情况TCP会使用Nagle算法发送数据,因为TCP/IP协议会给用户数据添加一些头部信息。比如hello,加上IP头部和TCP头部分别20Byte,就是45Byte。但是如果分开发h/e/l/l/o就是205Byte。
Nagle算法就是不会立马发送数据,而是积攒到了一定数量再将其组成一个较大的数据报发送。
5.3.4TTL
表示一个IP数据包的能够经过的最大路由器跳数,防止在网络中无限循环和收发。如果偏远地区经常收不到,就socket.ttl=较大的数字
5.3.5ReuseAddress
端口复用,可以让同一个端口被多个socket使用。可以用于重启服务器的时候使用。
5.3.6LingerState
设置套接字保持连接的时间。如果设为0,就会一直等到数据发完才关闭连接。设为10,就等10s再关闭。
但是过多的TIME_WAIT会占用系统资源,有时候需要快速释放资源。
5.4Close的恰当时机
LingerState可以让程序在关闭连接前发完系统缓冲区的数据,但是这不代表能将所有数据发送出去。
比如我们自己定义的writeQueue,就算开启LigerState仍然会丢失数据。
所以我们要用一个isClosing标志位来判断是否还有正在发送的数据,如果没有再调用socket.Close()
5.5异常处理
对于大部分的Socket API,需要将它们放在try-catch结构里面
心跳机制
TCP有一个连接检测机制,如果在指定时间内没有数据传送,会给对端发送一个信号,对端收到后,回送一个信号。如果一段时间内没有收到对方的响应,就进行重试,重试几次后,会认为网络不通,关闭socket。
游戏开发中,TCP的KeepAlive机制很鸡肋,因为一段时间往往代表着2小时。所以我们一般自己实现心跳机制,每隔1分钟向服务端发送PING消息,服务端收到后回应PONG消息,如果很久没有回应就关闭连接。
缺点:
- 在短暂的故障期内,引起良好连接被释放。
- PING和PONG消息占用了不必要的宽带
- 会让玩家花更多流量