Ejemplo n.º 1
0
        /// <summary>
        /// データをパースして、対応するセグメントを作成する.
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static Segment Parse(byte[] bytes, int offset, int length)
        {
            Segment ret = null;

            var flags = bytes[0];

            if (CheckFlag(flags, Type.SYN))
            {
                ret = new SynchronousSegment();
            }
            else if (CheckFlag(flags, Type.NUL))
            {
                ret = new NullSegment();
            }
            else if (CheckFlag(flags, Type.EAK))
            {
                ret = new ExtendAckSegment();
            }
            else if (CheckFlag(flags, Type.RST))
            {
                ret = new ResetSegment();
            }
            else if (CheckFlag(flags, Type.FIN))
            {
                ret = new FinishSegment();
            }
            else if (CheckFlag(flags, Type.ACK))
            {
                //var headerSize = bytes[1];

                if (length == RUDP_HEADER_LEN)
                {
                    // ACK
                    ret = new AcknowledgementSegment();
                }
                else
                {
                    // DAT
                    ret = new DataSegment();
                }
            }

            if (ret != null)
            {
                ret.ReadBytes(bytes, offset, length);
            }
            else {
                throw new ApplicationException();
            }

            return ret;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// データ送信.
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public int Send(byte[] bytes, int offset, int length)
        {
            if (this.IsClosed)
            {
                return 0;
            }

            int totalBytes = 0;

            while (totalBytes < length)
            {
                int sendBytes = Math.Min(
                    this.Parameter.MaxSegmentSize - Segment.RUDP_HEADER_LEN,
                    length - totalBytes);

                if (sendBytes <= 0)
                {
                    throw new ArgumentOutOfRangeException();
                }

                // NOTE
                // AcknowledgementSegment は受信したあとにハンドリングしないので
                // AcknowledgementSegment からのシーケンス番号は更新されない.
                // そのため、Listner - Client でシーケンス番号に齟齬が生じる.
                // そこで、DataSegment や FinishSegment などを送るときにシーケンス番号をリセットするように
                // LastInSequenceNumber ではなく、独自に管理しているシーケンス番号を使うようにする.

                var segment = new DataSegment(
                    this.Counter.NextSequenceNumber(),
                    this.Counter.GetLastInSequenceNumber(),
                    bytes,
                    offset,
                    length);

                SendAndQueueSegment(segment);

                totalBytes += length;
            }

            return totalBytes;
        }