Example #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;
        }
Example #2
0
        /// <summary>
        /// 終了.
        /// </summary>
        public void Close()
        {
            if (this.IsClosed)
            {
                return;
            }

            switch ((State)this.CurState)
            {
                case State.SYN_SENT:
                    // 接続待ちを起こす.
                    this.ConnectEvent.Set();
                    break;
                case State.SYN_RECV:
                case State.ESTABLISHED:
                    // NOTE
                    // AcknowledgementSegment は受信したあとにハンドリングしないので
                    // AcknowledgementSegment からのシーケンス番号は更新されない.
                    // そのため、Listner - Client でシーケンス番号に齟齬が生じる.
                    // そこで、DataSegment や FinishSegment などを送るときにシーケンス番号をリセットするように
                    // LastInSequenceNumber ではなく、独自に管理しているシーケンス番号を使うようにする.

                    var segment = new FinishSegment(this.Counter.NextSequenceNumber());
                    SendSegment(segment);

                    // TODO
                    // スレッドなどを止める.
                    // 現状は recv がブロッキングされるので、スレッドを止められない.
                    break;
                default:
                    break;
            }

            this.CurState.Store(State.CLOSED);

            this.VacantUnAckedSentSegListWait.Set();
            this.NotEmptyUnAckedSentSegListWait.Set();
            this.InSequenceSegWait.Set();
        }