Example #1
0
        /// <summary>
        /// 受信した接続要求(SYNchronous)セグメントを処理する.
        /// </summary>
        /// <param name="segment"></param>
        private void HandleSYNSegment(SynchronousSegment segment)
        {
            switch (this.CurState.Load())
            {
                case State.NONE:  // 未接続.
                    this.Counter.SetLastInSequenceNumber(segment.SequenceNumber);

                    this.CurState.Store(State.SYN_RECV);

                    // NOTE
                    // State.NONE 状態で SynchronousSegment を受信するのは Listener なので
                    // SynchronousSegment を送信し返すタイミングでシーケンス番号を新規設定する?
                    // でも、もらった番号をそのまま使えばいい気もするが・・・

                    var rand = new Random(Environment.TickCount);
                    var syncSegment = new SynchronousSegment(
                        this.Counter.SetSequenceNumber(rand.Next(MAX_SEQUENCE_NUMBER)),
                        this.Parameter == null ? new Parameter() : this.Parameter);

                    syncSegment.SetAcknowledgedNumber(segment.SequenceNumber);

                    SendAndQueueSegment(syncSegment);

                    this.UnAckedRecievedSegmentList.Remove(segment);

                    break;
                case State.SYN_SENT:    // 接続要求送信済み.
                    this.Counter.SetLastInSequenceNumber(segment.SequenceNumber);

                    // 返事を返す.
                    SendAcknowledgement(segment);

                    // 接続確立.
                    OpenConnection();

                    break;
            }
        }
Example #2
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 #3
0
        /// <summary>
        /// 接続.
        /// </summary>
        /// <param name="ep"></param>
        public void Connect(IPEndPoint ep)
        {
            this.Udp.Connect(ep);

            this.CurState.Store(State.SYN_SENT);

            var rand = new Random(Environment.TickCount);
            var segment = new SynchronousSegment(
                this.Counter.SetSequenceNumber(rand.Next(MAX_SEQUENCE_NUMBER)),
                this.Parameter);

            // 同期要求を送る.
            SendAndQueueSegment(segment);

            // 接続が確立されるまで待つ
            this.ConnectEvent.WaitOne();

            if (this.CurState != State.ESTABLISHED)
            {
                // TODO
                // ここから下は失敗したときの処理
            }
        }