示例#1
0
        public void Test2()
        {
            var aleData1 = new AleConnectionConfirm()
            {
                ServerID = 10,
            };

            var aleFrame1 = new AleFrame(1, 111, false, aleData1);

            aleFrame1.Version         = 1;
            aleFrame1.ApplicationType = 22;
            aleFrame1.SequenceNo      = 300;

            Assert.AreEqual(AleFrameType.ConnectionConfirm, aleFrame1.FrameType);

            var bytes = aleFrame1.GetBytes();

            var aleFrame2 = new AleFrame();

            aleFrame2.ParseBytes(bytes);

            Assert.AreEqual(aleFrame2.Version, aleFrame1.Version);
            Assert.AreEqual(aleFrame2.ApplicationType, aleFrame1.ApplicationType);
            Assert.AreEqual(aleFrame2.SequenceNo, aleFrame1.SequenceNo);
            Assert.AreEqual(aleFrame2.IsNormal, aleFrame1.IsNormal);

            var aleData2 = aleFrame2.UserData as AleConnectionConfirm;

            Assert.NotNull(aleData2);
            Assert.AreEqual(aleData1.ServerID, aleData2.ServerID);
        }
示例#2
0
        void ITcpConnectionObserver.OnAleFrameArrival(TcpConnection theConnection, AleFrame theFrame)
        {
            try
            {
                // 只处理ConnectionRequest帧。
                if (theFrame.FrameType == AleFrameType.ConnectionRequest)
                {
                    var aleData = theFrame.UserData as AleDataConnectionRequest;
                    var key     = this.BuildAleConnectionID(aleData.MasterID, aleData.SlaveID);

                    AleConnection aleConnection;
                    if (!_aleConnections.ContainsKey(key))
                    {
                        aleConnection = new AleConnection(aleData.SlaveID, aleData.MasterID);
                        _aleConnections.GetOrAdd(key, aleConnection);
                    }
                    else
                    {
                        aleConnection = _aleConnections[key];
                    }

                    // 交给AleConnection处理。
                    ((ITcpConnectionObserver)aleConnection).OnAleFrameArrival(theConnection, theFrame);

                    // 从临时链表中移除。
                    _tcpConnections.Remove(theConnection);
                }
            }
            catch (System.Exception /*ex*/)
            {
                _tcpConnections.Remove(theConnection);
                theConnection.Close();
            }
        }
示例#3
0
        public void Test3()
        {
            var aleData1 = new AleDataTransmission()
            {
                UserData = new byte[] { 100, 200 }
            };

            var aleFrame1 = new AleFrame(1, 111, false, aleData1);

            aleFrame1.Version         = 1;
            aleFrame1.ApplicationType = 22;
            aleFrame1.SequenceNo      = 300;

            Assert.AreEqual(AleFrameType.DataTransmission, aleFrame1.FrameType);

            var bytes = aleFrame1.GetBytes();

            var aleFrame2 = new AleFrame();

            aleFrame2.ParseBytes(bytes);

            Assert.AreEqual(aleFrame2.Version, aleFrame1.Version);
            Assert.AreEqual(aleFrame2.ApplicationType, aleFrame1.ApplicationType);
            Assert.AreEqual(aleFrame2.SequenceNo, aleFrame1.SequenceNo);
            Assert.AreEqual(aleFrame2.IsNormal, aleFrame1.IsNormal);

            var aleData2 = aleFrame2.UserData as AleDataTransmission;

            Assert.NotNull(aleData2);
            Assert.AreEqual(aleData1.UserData[0], aleData2.UserData[0]);
            Assert.AreEqual(aleData1.UserData[1], aleData2.UserData[1]);
        }
示例#4
0
        public override void SendUserData(byte[] maslPacket)
        {
            var aleData   = new AleDataTransmission(maslPacket);
            var seqNo     = (ushort)this.Context.SeqNoManager.GetAndUpdateSendSeq();
            var appType   = this.Context.RsspEP.ApplicatinType;
            var dataFrame = new AleFrame(appType, seqNo, false, aleData);

            // send
            if (this.Context.RsspEP.ServiceType == ServiceType.A)
            {
                this.Context.Tunnels.ToList().ForEach(connection =>
                {
                    if (connection.IsActive)
                    {
                        dataFrame.IsNormal = connection.IsNormal;
                        var bytes          = dataFrame.GetBytes();
                        connection.Send(bytes);
                    }
                });
            }
            else
            {
                dataFrame.IsNormal = false;
                var bytes = dataFrame.GetBytes();
                this.Context.Tunnels.ToList().ForEach(connection =>
                {
                    connection.Send(bytes);
                });
            }
        }
示例#5
0
        public void Test1()
        {
            var aleData1 = new AleConnectionRequest()
            {
                InitiatorID = 10, ResponderID = 20, @ServiceType = ServiceType.D
            };

            var aleFrame1 = new AleFrame(1, 111, false, aleData1);

            aleFrame1.Version         = 1;
            aleFrame1.ApplicationType = 22;
            aleFrame1.SequenceNo      = 300;

            Assert.AreEqual(AleFrameType.ConnectionRequest, aleFrame1.FrameType);

            var bytes = aleFrame1.GetBytes();

            var aleFrame2 = new AleFrame();

            aleFrame2.ParseBytes(bytes);

            Assert.AreEqual(aleFrame2.Version, aleFrame1.Version);
            Assert.AreEqual(aleFrame2.ApplicationType, aleFrame1.ApplicationType);
            Assert.AreEqual(aleFrame2.SequenceNo, aleFrame1.SequenceNo);
            Assert.AreEqual(aleFrame2.IsNormal, aleFrame1.IsNormal);

            var aleData2 = aleFrame2.UserData as AleConnectionRequest;

            Assert.NotNull(aleData2);
            Assert.AreEqual(aleData1.InitiatorID, aleData2.InitiatorID);
            Assert.AreEqual(aleData1.ResponderID, aleData2.ResponderID);
            Assert.AreEqual(aleData1.ServiceType, aleData2.ServiceType);
        }
示例#6
0
        public virtual void HandleDiFrame(AleTunnel theConnection, AleFrame theFrame)
        {
            var diData = theFrame.UserData as AleDisconnect;

            this.Context.Observer.OnAleUserDataArrival(diData.UserData);

            theConnection.Disconnect();
        }
示例#7
0
        void IAleTunnelObserver.OnAleFrameArrival(AleTunnel theConnection, AleFrame theFrame)
        {
            try
            {
                lock (_stateInputEventSyncLock)
                {
                    if (CheckFrame(theFrame))
                    {
                        // D类服务时,序列号有效;A类服务时,序列号无效。
                        if (_rsspEndPoint.ServiceType == ServiceType.D &&
                            theFrame.FrameType == AleFrameType.DataTransmission)
                        {
                            _seqNoManager.UpdateAckSeq(theFrame.SequenceNo);
                        }

                        //
                        if (theFrame.FrameType == AleFrameType.ConnectionRequest)
                        {
                            LogUtility.Info(string.Format("{0}: Received a CR frame on tcp connection(LEP={1}, REP={2}).",
                                                          this.RsspEP.ID, theConnection.LocalEndPoint, theConnection.RemoteEndPoint));

                            theConnection.Observer = this;

                            _currentState.HandleConnectionRequestFrame(theConnection, theFrame);
                        }
                        else if (theFrame.FrameType == AleFrameType.ConnectionConfirm)
                        {
                            LogUtility.Info(string.Format("{0}: Received a CC frame on tcp connection(LEP={1}, REP={2})).",
                                                          this.RsspEP.ID, theConnection.LocalEndPoint, theConnection.RemoteEndPoint));

                            _currentState.HandleConnectionConfirmFrame(theConnection, theFrame);
                        }
                        else if (theFrame.FrameType == AleFrameType.Disconnect)
                        {
                            _currentState.HandleDiFrame(theConnection, theFrame);
                        }
                        else if (theFrame.FrameType == AleFrameType.DataTransmission)
                        {
                            _currentState.HandleDataTransmissionFrame(theConnection, theFrame);
                        }
                    }
                    else if (_seqNoManager.IsBeyondRange(theFrame.SequenceNo))
                    {
                        throw new Exception(string.Format("检测到丢包,当前确认序号={0},收到的发送序号={1},TCP ID = {2}",
                                                          _seqNoManager.AckSeq, theFrame.SequenceNo, theConnection.ID));
                    }
                }
            }
            catch (System.Exception ex)
            {
                LogUtility.Error(string.Format("ALE: {0} : {1}", _rsspEndPoint.ID, ex));
                theConnection.Disconnect();
            }
        }
示例#8
0
        void IAleTunnelObserver.OnAleFrameArrival(AleTunnel theConnection, AleFrame theFrame)
        {
            try
            {
                // 只处理ConnectionRequest帧。
                if (theFrame.FrameType != AleFrameType.ConnectionRequest)
                {
                    throw new Exception(string.Format("在临时AleTunnel上收到了非CR帧,关闭此连接!本地终结点={0},远程终结点={1}。",
                                                      theConnection.LocalEndPoint, theConnection.RemoteEndPoint));
                }

                // 确认此连接是“AleServerTunnel对象”。
                var tunnel = theConnection as AleServerTunnel;
                if (tunnel == null)
                {
                    throw new Exception(string.Format("在非AleServerTunnel上收到了CR帧!本地终结点={0},远程终结点={1}。",
                                                      theConnection.LocalEndPoint, theConnection.RemoteEndPoint));
                }

                // 处理ALE帧。
                var aleCrData = theFrame.UserData as AleConnectionRequest;
                var key       = this.BuildSaiConnectionID(aleCrData.ResponderID, aleCrData.InitiatorID);

                SaiConnectionServer saiConnection;
                lock (_saiConnectionsLock)
                {
                    saiConnection = this.GetSaiConnection(key) as SaiConnectionServer;
                    if (saiConnection == null)
                    {
                        saiConnection = this.CreateSaiConnectionServer(aleCrData.InitiatorID);

                        this.AddSaiConnection(key, saiConnection);

                        saiConnection.Open();
                    }
                }

                // 交给SaiConnection处理。
                saiConnection.HandleAleConnectionRequestFrame(tunnel, theFrame);

                // 从临时链表中移除。
                _serverTunnels.Remove(tunnel);
            }
            catch (System.Exception ex)
            {
                LogUtility.Error(string.Format("{0}", ex));
                _serverTunnels.Remove(theConnection as AleServerTunnel);
                theConnection.Close();
            }
        }
示例#9
0
        public virtual void Disconnect(byte[] diSaPDU)
        {
            var seqNo   = (ushort)this.Context.SeqNoManager.GetAndUpdateSendSeq();
            var appType = this.Context.RsspEP.ApplicatinType;
            var aleData = new AleDisconnect(diSaPDU);

            var dataFrame = new AleFrame(appType, seqNo, false, aleData);
            var bytes     = dataFrame.GetBytes();

            var tcpLinks = this.Context.Tunnels.ToList();

            tcpLinks.ForEach(connection =>
            {
                connection.Send(bytes);
                connection.Disconnect();
            });
        }
示例#10
0
        protected void SendConnectionConfirmFrame(AleTunnel theConnection)
        {
            var au2Packet = this.Context.AuMsgBuilder.BuildAu2Packet();

            var ccData = new AleConnectionConfirm(this.Context.RsspEP.LocalID, au2Packet);

            // 构建AleFrame。
            ushort seqNo   = 0;
            var    appType = this.Context.RsspEP.ApplicatinType;
            var    ccFrame = new AleFrame(appType, seqNo, theConnection.IsNormal, ccData);

            // 发送。
            var bytes = ccFrame.GetBytes();

            theConnection.Send(bytes);

            LogUtility.Info(string.Format("{0}: Send CC frame via tcp connection(LEP = {1}, REP={2}).",
                                          this.Context.RsspEP.ID, theConnection.LocalEndPoint, theConnection.RemoteEndPoint));
        }
示例#11
0
        public override void HandleConnectionRequestFrame(AleTunnel theConnection, AleFrame theFrame)
        {
            var crData = theFrame.UserData as AleConnectionRequest;

            // 停止握手计时器。
            theConnection.StopHandshakeTimer();

            // 复位序号。
            this.Context.SeqNoManager.Initlialize();

            // 检查CR协议帧。
            this.CheckCrFrame(crData, theConnection);

            // 更新服务类型。
            this.Context.RsspEP.ServiceType = crData.ServiceType;

            // 将CR帧中的AU1提交到MASL(主要更新RandomB)。
            this.Context.Observer.OnAleUserDataArrival(crData.UserData);

            // 发送CC帧。
            this.SendConnectionConfirmFrame(theConnection);

            // 更新序号管理器的发送序号与确认序号。
            this.Context.SeqNoManager.GetAndUpdateSendSeq();
            this.Context.SeqNoManager.UpdateAckSeq(theFrame.SequenceNo);

            if (!this.Context.ContainsTunnel(theConnection))
            {
                // 接收到一个新的TCP连接。
                var args = new TcpConnectedEventArgs(theConnection.ID,
                                                     this.Context.RsspEP.LocalID, theConnection.LocalEndPoint,
                                                     this.Context.RsspEP.RemoteID, theConnection.RemoteEndPoint);
                this.Context.TunnelEventNotifier.NotifyTcpConnected(args);

                // 增加有效的连接个数。
                theConnection.IsHandShaken = true;
                this.Context.IncreaseValidConnection();

                // 保存TCP连接
                this.Context.AddConnection(theConnection);
            }
        }
示例#12
0
        private void HandleDataReceived(byte[] buffer, int bytesRead)
        {
            try
            {
                var aleFrameBytes = _streamPaser.ParseTcpStream(buffer, bytesRead);

                aleFrameBytes.ForEach(p =>
                {
                    var aleFrame = AleFrame.Parse(p);
                    this.Observer.OnAleFrameArrival(this, aleFrame);
                });
            }
            catch (System.Exception ex)
            {
                LogUtility.Error(ex.ToString());
                // 方式1:异常全部忽略,继续异步接收。
                // 方式2:断开连接。
                //this.Disconnect();
            }
        }
示例#13
0
        private bool CheckFrame(AleFrame theFrame)
        {
            // 1. 检查帧类型。
            // CR帧与CC帧固定有效。
            if (theFrame.FrameType == AleFrameType.ConnectionRequest ||
                theFrame.FrameType == AleFrameType.ConnectionConfirm)
            {
                return(true);
            }

            // 2. 检查序列号。
            // D类服务中序号才有效,A类服务中的序号都是0。
            if (_rsspEndPoint.ServiceType == ServiceType.A)
            {
                return(true);
            }
            else
            {
                return(_seqNoManager.IsExpected(theFrame.SequenceNo));
            }
        }
示例#14
0
        public override void HandleConnectionConfirmFrame(AleTunnel theConnection, AleFrame theFrame)
        {
            // 复位序号。
            this.Context.SeqNoManager.Initlialize();

            // 停止超时检测计时器。
            theConnection.StopHandshakeTimer();

            // 检查CC帧。
            var ccData = theFrame.UserData as AleConnectionConfirm;

            this.CheckCcFrame(ccData);

            // 如果CC帧中的应答方编号校验通过,则增加一个有效的连接。
            theConnection.IsHandShaken = true;
            this.Context.IncreaseValidConnection();

            // 更新序号管理器的发送序号与确认序号。
            this.Context.SeqNoManager.GetAndUpdateSendSeq();
            this.Context.SeqNoManager.UpdateAckSeq(theFrame.SequenceNo);

            // 将CC帧中的AU2提交到MASL。
            this.Context.Observer.OnAleUserDataArrival(ccData.UserData);
        }
示例#15
0
 public virtual void HandleDataTransmissionFrame(AleTunnel theConnection, AleFrame theFrame)
 {
     LogUtility.Error(string.Format("{0}: {1}.{2} not implement!",
                                    this.Context.RsspEP.ID, this.GetType().Name,
                                    new StackFrame(0).GetMethod().Name.Split('.').Last()));
 }
示例#16
0
 public void HandleAleConnectionRequestFrame(AleServerTunnel connection, AleFrame requestFrame)
 {
     _maslConnection.HandleAleConnectionRequestFrame(connection, requestFrame);
 }
示例#17
0
 public void HandleAleConnectionRequestFrame(AleServerTunnel connection, AleFrame requestFrame)
 {
     ((IAleTunnelObserver)_aleConnection).OnAleFrameArrival(connection, requestFrame);
 }