1、TCP的特点以及与应用
TCP提供一种面向连接的、可靠的字节流服务。面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据包之前必须先建立一个TCP连接。TCP建立连接需要经过三次握手,首先,客户端发送一段报文给服务器,表示我要连你,服务器收到报文后马上回复客户端,同意或者不同意你连我,最后客户端再发送一段报文给服务器表示确认要连接,经过这三次握手,客户端才能最终连接上服务器。TCP主要有这几个特点:TCP是面向连接的传输层协议;每个TCP连接只能有两个端点,而且只能是一对一通信,不能一点对多点直接通信;数据以字节流的方式传输;传输的数据无消息边界;TCP通过丢包重传、滑动窗口、数据排序、拥塞控制等机制来保证传输数据的可靠性。
一般,强联网类型的游戏都使用TCP,当然,有些对实时性要求很高的游戏也会将TCP与UDP配合使用,比如王者荣耀这类MOBA游戏,在实时战斗中会使用可靠UDP协议,来保证游戏数据的高效传输,弱联网类型的一般使用HTTP,HTTP为短链接,它基于TCP协议,当完成一次通讯就会马上断开连接。
2、如何维护一个长连接
在游戏过程中,玩家所处的网络环境是复杂多变的,有时因为糟糕的网络问题,会出现客户端掉线、延迟、丢包等问题,网络状况不好时UDP会丢包严重,TCP虽然是可靠,但也会在ip层丢包,只不过由于TCP的重传机制,能保证数据能传输到远程终端,但也会造成延迟。那么如何维护好一个长连接呢?那就是做好断线重连机制。
什么时候触发断线重连?
第一种判断方法:在网络糟糕的情况下,在客户端进行网络操作时经常会显示的抛出异常,比如NetworkException、Timeout等,这种情况下,就说明客户端已经无法与服务器通讯,这时就需要客户端主动发起对服务器连接。
第二种判断方法:使用心跳检测,可以服务器定时发心跳包给客户端,也可以客户端定时发心跳包给服务器,我认为最稳妥的应该是客户端发送心跳包给服务器,服务器收到后再回复一条确认收到的消息给客户端,心跳包只需简单设计就好,一般只包含消息头,不含消息体。当超过规定时间T没有收到心跳返回包时,就触发断线重连。
第三种判断方法:使用Keepalive,keepalive是在TCP中一个可以检测死连接的机制,是由TCP协议层实现的,具体使用方法我暂时也没去了解~
第四种判断方法:当手机客户端切回后台后一定时间又返回游戏,或者网络连接从wifi切到4G等情况下,可以主动触发一次重连操作。
断线重连的大致流程:

3、如何处理粘包分包问题
使用TCP协议做网络模块开发时,由于TCP本身的机制,如果发送的数据很小,那么会自动把一些小的数据合并在一起发送出去,但是接收端就没办法理解数据包并自行分开它,这就是粘包现象;而当一次发送的数据又过长的时候,TCP就会把该数据分成几部分发送出去,每次接收方就只会接受部分的数据,这就是分包现象。由于粘包和分包现象是在传输层发生的,我们只能在应用层想办法解决,处理粘包和分包有很多方法,这里介绍几种常见的方法:
第一种方法是在每个数据包前面加上该数据包的长度,作为该数据包的包头,当收到消息包时,先读取消息包头,得到消息包的长度,再根据这个长度去读取对应长度的字节,这样就能很好的解决粘包分包的问题。
第二种方法是在每个消息包的头部或尾部加上一个标识符,这个标识符不能是常用的字符,比如可以使用‘¥’这类平时不会出现在消息体中的字符,将它作为消息包界限,接收端在收到消息后就能根据这个界限方便的去做处理。
第三种方法是如果使用的是JSON这类字符串做传输,可以根据消息包的首尾字符,通过判断首尾‘{’和‘}’来组成一个完整的消息包。
4、使用TCP还是UDP
众所周知,C/S架构中,TCP使用广泛,UDP同样也有不少用武之地,先看一下UDP与TCP相比的区别:首先,UDP速度比TCP快,因为UDP不需要先与对方建立连接,也没有传输确认这一步骤,因此其速度会快不少;UDP一次性发送一个消息包,不需要考虑消息边界的问题;UDP可以使用广播或者组播的方式进行一对多传输;UDP由于没有可靠的消息传输机制,它的可靠性不如TCP,也不能保证有序传输。
游戏往往对数据的可靠性传输要求很高,似乎看起来只能使用TCP,然而,很多游戏对客户端数据同步要求特别高,比如英雄联盟和王者荣耀,使用TCP来传输实时战斗数据是行不通的,那还是只能在UDP上想办法 ,通过对UDP进行一层可靠性封装,可以使UDP同样具有类似TCP传输可靠有序的特点。英雄联盟开发时使用的是Enet,ENet提供一个相对简单的以及稳健的位于UDP顶部的网络通信层。其提供的主要功能是可选的可靠按顺序的传送数据包。王者荣耀使用的似乎是KCP,KCP是一个快速可靠协议,它主要的设计目的是为了解决在网络拥堵的情况下TCP协议网络速度慢的问题,增大网络传输速率,但相当于TCP而言,会相应的牺牲一部分带宽。KCP没有规定下层传输协议,一般用UDP作为下层传输协议。提供类似这种可靠UDP服务的还有UDT等,在GitHub上可以找到不少这类项目。
5、使用哪种网络传输数据格式
在做客户端服务器通讯前,要选择一种网络传输数据格式,在做选择时,都需要考虑几点:第一是数据大小,这关系到占用带宽和传输效率,应该尽量不要有多余的数据;第二点是可拓展性、可维护性,必须支持序列化及反序列化消息中用到的数据结构;第三点是数据安全性,有些数据是敏感数据,需要进行加密处理;第四点是是否跨平台支持;第五点是消息可读性,这点不重要,但消息可读性高的话,调试时方便。
游戏开发中,主要的网络传输数据格式有Json、Xml、Protobuf,以及自定义二进制数据包,在很多时候,我们都使用Json和Xml,因为使用简单,可读性高,调试方便,但它们属于文本,占用空间稍大,显得有些臃肿。自定义二进制数据格式虽然体积小,传输高效,但致命的缺点是可扩展性差,在编写和解析数据包时很容易出错,而且当需要编写一些数据结构时会比较麻烦,因此这种方式只适合小项目。Protobuf是一种轻便高效的结构化数据存储格式,Protobuf可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式,目前提供了C++、Java、Python、C#等多种语言的API,很适合用于网络游戏的消息结构体定义上。相对于XML文件和Json文件,它的性能更好,效率更高。
如有错误,欢迎指正!
- Http 和TCP的关系,TCP长连接和短连接有什么区别?
HTTP 协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用.由于HTTP在 ...
- TCP 长连接与短连接的区别
TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次握手的 ...
- TCP长连接与短连接
1.概念区别 所谓TCP短连接,是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接.也就是说TCP连接维持的时间比较短.一般银行网页数据交互都使用短连接.再比如说htt ...
- TCP长连接与短连接的区别
http://www.cnblogs.com/liuyong/archive/2011/07/01/2095487.html 1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,se ...
- 多进程解决datasnap支持的tcp长连接数量少的问题
对于实时采集数据的项目,应用场景比如是这样的:5000客户端,每个客户端每隔500MS要给服务器上传一次数据. 大家知道,像INDY这种阻塞型的通信控件,所能支持的TCP长连接的一般地不能超过1000 ...
- TCP长连接与短连接的原理及区别
一.当网络通信时采用TCP协议时: 1.过程: 第一步:(在真正的读写操作之前)Server 和Client 之间必须建立一个连接,连接的建立需要三次握手 经典的三次握手示意图: 第二步:进行读写操 ...
- [转载] TCP长连接与短连接的区别
转载自http://www.cnblogs.com/liuyong/archive/2011/07/01/2095487.html 1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前 ...
- UNIX网络编程——TCP长连接与短连接的区别
一.TCP短连接 我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接.client向server发送消息,server回应client,然后 ...
- TCP长连接与短连接、心跳机制
1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...
随机推荐
- js五道经典练习题--第四道qq好友列表
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- js-图片时间(倒计时)
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- [php] php - json_encode 函数
json_encode()函数, $arr= array("key"=>null); echo json_encode($arr);{"key":null ...
- .NET高级代码审计(第五课) .NET Remoting反序列化漏洞
0x00 前言 最近几天国外安全研究员Soroush Dalili (@irsdl)公布了.NET Remoting应用程序可能存在反序列化安全风险,当服务端使用HTTP信道中的SoapServerF ...
- websevice动态控制访问ip
一般而言webservice是部署在哪台服务器,然后它的address location就是指向哪个,但是由于有些情况处于各种原因,如网络策略,需要先访问某个ip之后再进行跳转到一个ip,这个时候就需 ...
- Html Agility Pack解析Html(C#爬虫利器)
有个需求要写网络爬虫,以前接触过一个叫Html Agility Pack这个解析html的库,这次又要用到,然而发现以前咋用的已经不记得了,现在从头开始记录一下使用过程. Html Agility P ...
- Asp.Net MVC EF之二:原生EF插入,更新数据的正确方法
引言 EF是相对与Dapper.NHibernate官方首推的ORM框架,其在开发过程中的方便,快捷毋庸置疑的,但由于EF本身的一些缓存机制.跟踪机制,所以在使用时有些地方需要特别注意. 下面我将自己 ...
- 手机app有了短信验证码还有没必要有图片验证码?
当然有必要,这里我们来聊一个恶意短信验证的案例,通过这个案例我们就能更好理解短信验证码和图片验证码这两者的关系了. 讨论防止恶意短信验证之前,我们先来看看什么是恶意短信验证及出现的原因. 恶意短信验证 ...
- 小记 ArchLinux 下 Typora 无法输入中文
今天准备写一篇 Linux 下的打印机文章,打开 Typora 时我发现不管我怎么设置都无法输入中文. pacman -R typora pacman -S typora 重新安装是无效的,我突然想起 ...
- 设计模式《JAVA与模式》之访问者模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要 ...