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文件,它的性能更好,效率更高。
 
如有错误,欢迎指正!

TCP长连接的一些事儿的更多相关文章

  1. Http 和TCP的关系,TCP长连接和短连接有什么区别?

    HTTP 协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用.由于HTTP在 ...

  2. TCP 长连接与短连接的区别

    TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次握手的 ...

  3. TCP长连接与短连接

    1.概念区别 所谓TCP短连接,是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接.也就是说TCP连接维持的时间比较短.一般银行网页数据交互都使用短连接.再比如说htt ...

  4. TCP长连接与短连接的区别

    http://www.cnblogs.com/liuyong/archive/2011/07/01/2095487.html 1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,se ...

  5. 多进程解决datasnap支持的tcp长连接数量少的问题

    对于实时采集数据的项目,应用场景比如是这样的:5000客户端,每个客户端每隔500MS要给服务器上传一次数据. 大家知道,像INDY这种阻塞型的通信控件,所能支持的TCP长连接的一般地不能超过1000 ...

  6. TCP长连接与短连接的原理及区别

    一.当网络通信时采用TCP协议时:  1.过程: 第一步:(在真正的读写操作之前)Server 和Client 之间必须建立一个连接,连接的建立需要三次握手 经典的三次握手示意图: 第二步:进行读写操 ...

  7. [转载] TCP长连接与短连接的区别

    转载自http://www.cnblogs.com/liuyong/archive/2011/07/01/2095487.html 1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前 ...

  8. UNIX网络编程——TCP长连接与短连接的区别

    一.TCP短连接 我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接.client向server发送消息,server回应client,然后 ...

  9. TCP长连接与短连接、心跳机制

    1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...

随机推荐

  1. 用户访问网页流程、DNS 解析流程

    一.用户访问流程 二.DNS解析流程 DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于 TCP/IP 网络,它所提供的 ...

  2. adb push 和 adb pull命令

    adb push命令 :从电脑上传送文件到手机: adb pull命令 :从手机传送文件到电脑上             @Cocos 下次需要权限的目录可以执行chmod 777 目录名      ...

  3. Java学习--基本数据类型的定义和运算

    例1: public class DataDemo05{ public static void main(String args[]){ char ch1 = '\"' ; // 表示的是一 ...

  4. Python自动化开发 - 进程、线程(一)

    本节内容 1.操作系统发展史 2.进程和线程 3.Python threading 模块 一.操系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统 ...

  5. YOLO end-to-end

    1.YOLO: You Only Look Once:Unified, Real-Time Object Detection YOLO是一个可以一次性预测多个Box位置和类别的卷积神经网络,能够实现端 ...

  6. 利用GDI+处理图像,包括图像的的裁剪显示、转置、镜像、简单旋转、变形等。

    一.图像的裁剪显示:有时程序需要显示图像的一部分而不是全部.实例代码如下: CDC* pDC = GetDC(); Graphics graph(pDC->GetSafeHdc()); Imag ...

  7. winform执行程序报错:已停止工作,windows正在检查该问题的解决方案

    每次运行程序时都会弹出错误框:winform已停止工作,windows正在检查该问题的解决方案 事件查看器错位信息: 错误应用程序名称: TMS_winform.exe,版本: 1.0.0.0,时间戳 ...

  8. spring cloud 学习(6) - zuul 微服务网关

    微服务架构体系中,通常一个业务系统会有很多的微服务,比如:OrderService.ProductService.UserService...,为了让调用更简单,一般会在这些服务前端再封装一层,类似下 ...

  9. Vue.js之下拉列表及选中触发事件

    老早就听说了Vue.js是多么的简单.易学.好用等等,然而我只是粗略的看了下文档,简单的敲了几个例子,仅此而已. 最近由于项目的需要,系统的看了下文档,也学到了一些东西. 废话不多说,这里要说的是下拉 ...

  10. mysql添加类似oracle的伪列及查看表信息

    sql格式: AS rownum, table_name.* ) r, table_name; AS rownum, table_name.字段1, table_name.字段2, table_nam ...