/// <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; } }
/// <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; }
/// <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 // ここから下は失敗したときの処理 } }