コード例 #1
0
		public virtual IEnumerable<object> Unpack(Zongsoft.Common.Buffer buffer)
		{
			int availableLength;

			while(buffer.CanRead())
			{
				//如果当前头部缓存指针位置小于包头的长度,则必须先读取头部数据
				if(_contentLength == 0 && _headOffset < HEAD_LENGTH)
				{
					//从当前接受缓存中读取剩下的包头数据
					availableLength = buffer.Read(_headBuffer, _headOffset, HEAD_LENGTH - _headOffset);

					//将当前头部缓存指针加上当前实际读取的长度
					_headOffset += availableLength;

					//如果当前头部缓存指针位置仍然小于包头长度,则说明当前接数据缓存区数据量不够,
					//即本次接收到的缓存数据已被读完,故直接退出当前方法。
					if(_headOffset < HEAD_LENGTH)
						yield break;

					//至此头部数据接收完毕,将头部缓存解析成包头实体
					_head = this.ResolveHeader(_headBuffer);

					//如果包头指示当前数据包的实际内容长度为零,则说明此包为空包
					if(_head.TotalLength == 0 || _head.ContentLength == 0)
					{
						//重置缓存指针位置,以指示下次需要进行包头解析
						_headOffset = 0;
						_contentLength = 0;

						//接着处理下一个小包
						continue;
					}

					//映射当前数据包对应的缓存区。
					if(!_bufferStates.ContainsKey(_head.SequenceId))
					{
						var bufferManager = this.GetBufferManager();
						var id = bufferManager.Allocate(_head.TotalLength);
						_bufferStates[_head.SequenceId] = new BufferState(bufferManager.GetStream(id));
					}
				}

				//计算出本次要接受的内容长度
				int contentLength = _contentLength == 0 ? _head.ContentLength : _contentLength;

				//定义当前接收的数据包对应的缓存状态对象
				BufferState bufferState;

				//从缓存容器中获取当前大包的缓存状态对象
				if(!_bufferStates.TryGetValue(_head.SequenceId, out bufferState))
					throw new InvalidOperationException("Can not obtain the BufferCache with sequence-id.");

				//将接收到的数据写入缓存区
				availableLength = buffer.Read(bufferState.BufferStream, contentLength);
				//更新当前缓存状态中的缓存数
				bufferState.BufferedSize += availableLength;
				//设置下次要接收的内容长度
				_contentLength = contentLength - availableLength;

				//如果下次要接收的内容长度为零,则指示下次接收要先进行包头的处理,即将头缓存偏移量置零
				if(_contentLength == 0)
					_headOffset = 0;

				//如果整个大包全部接受完毕
				if(bufferState.BufferedSize == _head.TotalLength)
				{
					//重置缓存指针位置,以指示下次需要进行包头解析
					_headOffset = 0;
					_contentLength = 0;

					//重置当前缓存区流的指针
					bufferState.BufferStream.Position = 0;

					//将当前接收的数据包从缓存映射中删除
					_bufferStates.Remove(_head.SequenceId);

					yield return bufferState.BufferStream;
				}
			}
		}
コード例 #2
0
		public virtual IEnumerable<Zongsoft.Common.Buffer> Pack(Zongsoft.Common.Buffer buffer)
		{
			if(buffer == null || buffer.Count == 0)
			{
				//遍历返回字节组缓存信息
				yield return new Zongsoft.Common.Buffer(new byte[HEAD_LENGTH], 0);
			}

			var sequenceId = System.Threading.Interlocked.Increment(ref _sequenceId);
			var bytes = new byte[_bufferEvaluator.GetBufferSize(buffer.Count)];
			int contentLength = 0;

			while((contentLength = buffer.Read(bytes, HEAD_LENGTH, bytes.Length - HEAD_LENGTH)) > 0)
			{
				//设置包的头部字段
				this.SetPackageHead(bytes, sequenceId, buffer.Count, contentLength);

				//遍历返回字节组缓存信息
				yield return new Zongsoft.Common.Buffer(bytes, 0, HEAD_LENGTH + contentLength);

				//注意:一定要重新分配缓存数组,不然同一个缓存在高速发送过程中肯定会发生写入覆盖
				bytes = new byte[_bufferEvaluator.GetBufferSize(buffer.Count)];
			}
		}