标签:
磨刀不误砍柴工,让我们从概念入手,逐步深入。
图4
图5
图6
一般是包头|Header|+包体|Body|+包尾|End|组成,有时候包尾部分也直接归入Body部分,形成|Header|+|Body|的结构。
包尾部分的信息一般用于校验包的完整性或者合法性等。
包头长度,信息字段的位置一般都是固定的,必须包含的字段一般有“包的长度(packetLen)”和“操作码(cmd)”(如图6),提供长度是为了方面我们解析数据包,而提供操作码是为了让程序知道,该条信息是要做什么操作。除以上两个字段,其他字段根据需要增减。
Socket数据处理流程:
既然上面我们人为的给数据进行了封包,那么我们处理数据就是以包为单位进行处理的。
1、 因为包头|Header|长度固定,当收到数据时,先检验缓冲区有效数据长度,是否大于等于包头长度,如果小于包头长度,则说明数据不够,则继续等待下一次数据的到来, 如果大于包头长度,则读取包头长度的数据,并按一定的格式解析包头数据,从包头中获取到包的长度(packetLen),此时包头处理基本完毕。
2、 根据包头读取到的packetLen,从而计算出包体部分的数据长度(比如bodyLen),再判断缓存区剩余数据长度是否大于等于bodyLen,如果不是,同样等待, 如果是,则从缓存区读出包体部分,进而按照一定的格式读取里面的数据(例如readInt(),readShort()…);此时包数据基本读取完毕!
3、 上面我们说过网络中的字节流没有界线的,因此我们该知道每次到达的数据,也就是缓冲区的数据,有可能不止一个数据包,因此需要循环执行 1,2步。
验证包的完整性和合法性:
之前说过我们在包尾或者是包体的最后位置会适当加上一些信息,来验证包的完整性或者合法性。
举个例子,我们通过一定的规则,把包体的数据位置顺序打乱,最后在包尾加上规则信息,以便接收端能按同样的规则解析还原数据,再通过两端比较,就知道包是否完整和合法等 其实要验证包是否合法,有很多的方法。
比如说判断包头操作码cmd的范围,传的数据长度是否跟包头声明的长度对应,或者整个包长度是否超过最大包的限制等等,不同的人有不同的做法,但目的基本是一样的。
时间有限,代码就不写了。
网络编程优化:
我们知道TCP有一系列的流量控制,网络拥塞控制的处理方案。但在AS3中,Adobe封装的太好了,导致很多底层东西AS目前都碰不了。 唯一我们能给点安慰的,就是基于TCP流量控制这一点上。
来重温一下:
TCP 还能提供流量控制。TCP 连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这将防止较快主机致使较慢主机的缓冲区溢出。
因此我们很自然的想到,尽量保持接收方TCP缓冲区有足够的容量,以便较快发送主机能及时发出数据,防止阻塞。
既然这样,那么AS客户端的一般保险处理方式是采取“快读取慢解析”的一种思路,也就是说当有接收到数据,我们会使用ByteArray一次性读取缓冲区的数据,然后再进行解包操作。
不过这里有个疑问,大伙可以研究探讨: Socket 类和ByteArray类同样实现了IDataInput, IdataOutput接口,那是不是socket其实已经实现了跟我们利用ByteArray存取数据的预防措施呢,也就是说内部数据存储部分跟 ByteArray具有同样的实现,如果是的话,那我们是不需要做 (&&)部分提及的把缓存区数据一次性写进 ByteArray后再进行包解析操作的方式,如果不是,那么还是实现 (&&):这一步来得保险,Adobe封装太好了,大伙可以研究下这里。
标签:
原文地址:http://www.cnblogs.com/-yan/p/4584293.html