/// <summary>
        /// Initialize net component and connect to remote server.
        /// </summary>
        /// <param name="remoteAddress">The address of remote server to connect.</param>
        /// <param name="remotePort">The port of remote server to connect.</param>
        public Boolean Initialize(String remoteAddress, Int32 remotePort)
        {
            // �ͻ��˴���IPV6��ʱ���߼�����Ҫ�õ�
#if UNITY_5_3_OR_NEWER
            if (Application.platform == RuntimePlatform.IPhonePlayer)
            {
                String        newServerIp      = "";
                AddressFamily newAddressFamily = AddressFamily.InterNetwork;
                getIPType(remoteAddress, remotePort.ToString(), out newServerIp, out newAddressFamily);
                if (!string.IsNullOrEmpty(newServerIp))
                {
                    remoteAddress = newServerIp;
                }
            }
#endif

            // analyze the ip address and port info
            IPAddress myIp;
            if (IPAddress.TryParse(remoteAddress, out myIp))
            {
                //strMsg = String.Format("BuildPeer TryParse {0} success", remoteAddress);
                //Debug.WriteLine(strMsg);

                m_ipEndPoint = new IPEndPoint(myIp, remotePort);
            }
            else
            {
                //strMsg = String.Format("BuildPeer GetHostEntry {0} fail", remoteAddress);
                //Debug.WriteLine(strMsg);
                return(false);
            }

            // Do some cleanup if necessery
            if (State != ConnectionState.None)
            {
                Close();
            }

            // Clean all messages of last connection
            RecvQueue.Clear();

            // Clean all event args of last connection
            m_connEventArg    = new SocketAsyncEventArgs();
            m_receiveEventArg = new SocketAsyncEventArgs();

            // init event args
            m_connEventArg.Completed     += new EventHandler <SocketAsyncEventArgs>(OnCompletedForConnect);
            m_connEventArg.RemoteEndPoint = m_ipEndPoint;
            m_receiveEventArg.Completed  += new EventHandler <SocketAsyncEventArgs>(OnCompletedForReceive);
            m_receiveEventArg.SetBuffer(new byte[ProtoConst.MAX_PACKAGE_LENGTH], 0, ProtoConst.MAX_PACKAGE_LENGTH);

            // Change state
            State = ConnectionState.Connecting;

            // Create work resource
            RecvCache = new MessageBlock((int)ConnectionConst.CACHE_MAX_BYTE);

            StartConnectionWork();
            return(true);
        }
        //The callback of BeginSend on fuction "SendMessage"
        private void OnCompletedForSendImpl(SocketAsyncEventArgs e)
        {
            try
            {
                if (e.SocketError == SocketError.Success)
                {
                    return;
                }
                else//发生故障了 就抛一个异常进行处理
                {
                    throw new Exception("The result of SendAsync is not correct");
                }
            }
            catch (Exception ex)
            {
                // Client exception means connection is disconnected
                CCMSGConnectionSendFailure failureMsg = new CCMSGConnectionSendFailure();
                failureMsg.ExceptionInfo = ex.ToString();
                lock (RecvQueue)
                {
                    RecvQueue.Enqueue(new KeyValuePair <int, object>(failureMsg.MessageId, failureMsg));
                }
                goto BREAK_CONNECT;
            }
BREAK_CONNECT:
            lock (RecvQueue)
            {
                if (State == ConnectionState.Established)
                {
                    State = ConnectionState.Closed;
                    var vMsg = new CCMSGConnectionBreak();
                    RecvQueue.Enqueue(new KeyValuePair <int, object>(vMsg.MessageId, vMsg));
                }
            }
        }
Exemple #3
0
        public async Task Stop()
        {
            await _group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));

            //
            RecvQueue.Clear();
            SendQueue.Clear();
        }
Exemple #4
0
        private void Setup(uint sequenceNumber, uint acknowlegementNumber)
        {
            this.send_queue = new SendQueue(acknowlegementNumber, Socket.packet_size);

            this.recv_queue = new RecvQueue(sequenceNumber, 1);

            this.byte_queue = new ByteQueue();

            this.OnConnect();
        }
        ///// <summary>
        ///// shutdown the socket
        ///// </summary>
        //public void Shutdown()
        //{
        //    try
        //    {
        //        lock (_lockSocket)
        //        {
        //            ////Console.WriteLine("Shutdown::lock (_lockPeer)");
        //            ConnSocket.Shutdown(SocketShutdown.Both);
        //        }

        //    }
        //    catch (Exception)
        //    {
        //        //String msg = String.Format("{0}:{1}", ex.GetType().ToString(), ex.Message);
        //        //Debug.WriteLine(msg);
        //        //Console.WriteLine(msg);
        //        //throw ex;
        //    }
        //    //Console.WriteLine("Client SHUTDOWN!");
        //}

        /// <summary>
        /// 断开soket
        /// </summary>
        private void SocketDisconnect()
        {
            try
            {
                if (ConnSocket != null)
                {
                    lock (_lockSocket)
                    {
                        // 启动断开连接的timer
                        if (m_disconnectTimer == null)
                        {
                            m_disconnectTimer = new Timer((c) =>
                            {
                                if (ConnSocket.Connected)
                                {
                                    return;
                                }
                                if (State != ConnectionState.Disconnecting)
                                {
                                    return;
                                }

                                // 记录日志
                                Debug.WriteLine(string.Format("SocketDisconnect Disconnected timer start..."));
                                FireEventOnLogPrint("Disconnect.Timer" + "state=" + State);

                                // 设置状态
                                State = ConnectionState.Closed;

                                // 发送连接断开的消息
                                var vMsg = new CCMSGConnectionBreak();
                                RecvQueue.Enqueue(new KeyValuePair <int, object>(vMsg.MessageId, vMsg));

                                // 清理timer
                                if (m_disconnectTimer != null)
                                {
                                    m_disconnectTimer.Dispose();
                                    m_disconnectTimer = null;
                                }
                            }, null, 500, 1000); // 500毫秒后启动, 1000毫秒检查一次
                        }

                        ConnSocket.Shutdown(SocketShutdown.Both);
                        //ConnSocket.Disconnect(false);
                    }
                }
            }
            catch (Exception ex)
            {
                String msg = String.Format("{0}:{1}", ex.GetType().ToString(), ex.Message);
                Debug.WriteLine(msg);
                //throw ex;
            }
        }
        /// <summary>
        /// Get underline protocol message.
        /// </summary>
        /// <returns>If exist message return it ,or reutrn null.</returns>
        public KeyValuePair <int, object> GetMessagePair()
        {
            KeyValuePair <int, object> msgPair = new KeyValuePair <int, object>(0, null);

            lock (RecvQueue)
            {
                if (RecvQueue.Count > 0)
                {
                    var vMsg = RecvQueue.Dequeue();
                    return(vMsg);
                }
            }
            return(msgPair);
        }
Exemple #7
0
        Task recvProcess() => Task.Run(async() =>
        {
            var knownPackets = new List <Tuple <ErebusAddress, long> >();
            Log.RecordEvent(this, $"Receive process started for instance at {Address}.", LogEntrySeverity.Info);
            while (process)
            {
                try
                {
                    if (RecvTSM.RunSafe(() =>
                    {
                        if (RecvQueue.Count > 0)
                        {
                            var p = RecvQueue.Dequeue();
                            Log.RecordEvent(this, $"Received packet {p.Identifier} from {p.Source} to {p.Destination} on port {p.Port} ({p.Data.Length} bytes)", LogEntrySeverity.Info);
                            if (knownPackets.Contains(Tuple.Create(p.Source, p.Identifier)))
                            {
                                return(false);
                            }
                            if (p.Destination == Address || p.Destination == ErebusAddress.Broadcast)
                            {
                                switch (p.Port >> 14)
                                {
                                case 0:
                                    Task.Run(() => RawProtocolBase.HandlePacket(p, this));
                                    break;

                                case 1:
                                    Task.Run(() => BCPProtocolBase.HandlePacket(p, this));
                                    break;
                                }
                            }
                            if (p.Destination != Address)
                            {
                                SendTSM.RunSafe(() => SendQueue.Enqueue(p));
                            }
                            knownPackets.Add(Tuple.Create(p.Source, p.Identifier));
                            return(false);
                        }
                        return(true);
                    }))
                    {
                        await Task.Delay(5);
                    }
                }
                catch (Exception e)
                {
                    Log.RecordEvent(this, $"Exception in main instance receive thread: {e.Message}", LogEntrySeverity.Warning);
                }
            }
        });
        private void OnCompletedForConnectImpl(SocketAsyncEventArgs e)
        {
            try
            {
                if (e.SocketError == SocketError.Success)
                {
                    /// Change connection state to ready
                    State = ConnectionState.Established;

                    // as soon as the client is connected, post a receive to the connection
                    if (!ConnSocket.ReceiveAsync(m_receiveEventArg))
                    {
                        OnCompletedForReceiveImpl(m_receiveEventArg);
                    }

                    /// Make a connection ready notification
                    CCMSGConnectionReady ccReadyMsg = new CCMSGConnectionReady();
                    RecvQueue.Enqueue(new KeyValuePair <int, object>(ccReadyMsg.MessageId, ccReadyMsg));
                    return;
                }
                else
                {
                    goto FAIL_CONNECT;
                }
            }
            catch
            {
                goto FAIL_CONNECT;
            }

FAIL_CONNECT:
            CCMSGConnectionFailure ccFailMsg = new CCMSGConnectionFailure();

            lock (RecvQueue)
            {
                RecvQueue.Enqueue(new KeyValuePair <int, object>(ccFailMsg.MessageId, ccFailMsg));
            }
            State = ConnectionState.Closed;
        }
        private void OnCompletedForReceiveImpl(SocketAsyncEventArgs e)
        {
            //Log.Info("接收到消息 Count = "+ e.BytesTransferred);
            // Log.Info("sadsadsadsa " + e.BytesTransferred);
            try
            {
                //Log.Info($"SocketError :{ e.SocketError}");
                if (e.SocketError == SocketError.Success && e.BytesTransferred != 0)
                {
                    // Log.Info("开始处理消息");
                    // at first, write state.buffer to recvcache
                    RecvCache.Write(e.Buffer, e.BytesTransferred);

                    //Debug.WriteLine(string.Format("OnCompletedForReceiveImpl Receive {0} RecvCache.Length={1}", e.BytesTransferred, RecvCache.Length));

                    // second, push the msg to recvqueue and decode message
                    while (true)
                    {
                        ushort msgId = 0;
                        bool   flag;
                        object msg = ProtoHelper.DecodeMessage(RecvCache, out msgId, out flag);
                        //Log.Msg(msg.GetType());
                        if (msg == null)
                        {
                            break;
                        }
                        lock (RecvQueue)
                        {
                            var eMsg = new CCMSGConnectionRevMsg();

                            eMsg.MessageInfo.Message = msg as IMessage;
                            eMsg.MessageInfo.Opcode  = (ushort)msgId;
                            eMsg.MessageInfo.flag    = flag;
                            //     Log.Info("接收到消息  并且丢进了队列");
                            RecvQueue.Enqueue(new KeyValuePair <int, object>(eMsg.MessageId, eMsg));
                        }

                        // all cache is handled
                        if (RecvCache.Length == 0)
                        {
                            break;
                        }
                    }
                    //Debug.WriteLine(string.Format("OnCompletedForReceiveImpl Receive End, RecvCache.Length={0}", RecvCache.Length));
                    RecvCache.Crunch();

                    // third, restart the async receive process
                    m_receiveEventArg.SetBuffer(0, ProtoConst.MAX_PACKAGE_LENGTH);
                    if (!ConnSocket.ReceiveAsync(m_receiveEventArg))
                    {
                        OnCompletedForReceiveImpl(m_receiveEventArg);
                    }
                    return;
                }
                else
                {
                    throw new Exception(string.Format("The result of ReceiveAsync is not correct, SocketError={0} BytesTransferred={1}", e.SocketError, e.BytesTransferred));
                }
            }
            catch (Exception ex)
            {
                // Client exception means connection is disconnected
                // Or, there is an bad message format in byte stream
                CCMSGConnectionRecvFailure eMsg = new CCMSGConnectionRecvFailure();
                eMsg.ExceptionInfo = ex.ToString();
                lock (RecvQueue)
                {
                    RecvQueue.Enqueue(new KeyValuePair <int, object>(eMsg.MessageId, eMsg));
                }
                goto BREAK_CONNECT;
            }

BREAK_CONNECT:
            // when receive action is over, which represents that socket can't receive any data
            lock (RecvQueue)
            {
                if (State == ConnectionState.Established ||
                    State == ConnectionState.Disconnecting)  // 这个状态是为了让客户端主动断开服务器的时候
                {
                    State = ConnectionState.Closed;
                    var vMsg = new CCMSGConnectionBreak();
                    RecvQueue.Enqueue(new KeyValuePair <int, object>(vMsg.MessageId, vMsg));
                }
            }
        }
        private void OnCompletedForReceiveImpl(SocketAsyncEventArgs e)
        {
            try
            {
                if (e.SocketError == SocketError.Success && e.BytesTransferred != 0)
                {
                    // at first, write state.buffer to recvcache
                    RecvCache.Write(e.Buffer, e.BytesTransferred);

                    //Debug.WriteLine(string.Format("OnCompletedForReceiveImpl Receive {0} RecvCache.Length={1}", e.BytesTransferred, RecvCache.Length));

                    // second, push the msg to recvqueue and decode message
                    while (true)
                    {
                        var    msgId = 0;
                        object msg   = ProtoHelper.DecodeMessage(RecvCache, Provider, out msgId);
                        if (msg == null)
                        {
                            break;
                        }
                        lock (RecvQueue)
                        {
                            RecvQueue.Enqueue(new KeyValuePair <int, object>(msgId, msg));
                        }

                        // all cache is handled
                        if (RecvCache.Length == 0)
                        {
                            break;
                        }
                    }
                    //Debug.WriteLine(string.Format("OnCompletedForReceiveImpl Receive End, RecvCache.Length={0}", RecvCache.Length));
                    RecvCache.Crunch();

                    // third, restart the async receive process
                    m_receiveEventArg.SetBuffer(0, ProtoConst.MAX_PACKAGE_LENGTH);
                    if (!ConnSocket.ReceiveAsync(m_receiveEventArg))
                    {
                        OnCompletedForReceiveImpl(m_receiveEventArg);
                    }
                    return;
                }
                else
                {
                    throw new Exception(string.Format("The result of ReceiveAsync is not correct, SocketError={0} BytesTransferred={1}", e.SocketError, e.BytesTransferred));
                }
            }
            catch (Exception ex)
            {
                // Connection exception means connection is disconnected
                // Or, there is an bad message format in byte stream
                CCMSGConnectionRecvFailure eMsg = new CCMSGConnectionRecvFailure();
                eMsg.ExceptionInfo = ex.ToString();
                lock (RecvQueue)
                {
                    RecvQueue.Enqueue(new KeyValuePair <int, object>(eMsg.MessageId, eMsg));
                }
                goto BREAK_CONNECT;
            }

BREAK_CONNECT:
            // when receive action is over, which represents that socket can't receive any data
            lock (RecvQueue)
            {
                if (State == ConnectionState.Established ||
                    State == ConnectionState.Disconnecting)  // ���״̬��Ϊ���ÿͻ��������Ͽ���������ʱ��
                {
                    State = ConnectionState.Closed;
                    var vMsg = new CCMSGConnectionBreak();
                    RecvQueue.Enqueue(new KeyValuePair <int, object>(vMsg.MessageId, vMsg));
                }
            }
        }
Exemple #11
0
        private async void Start(string serverIp, short serverPort)
        {
            Func <RT_MSG_TYPE, CipherContext, ICipher> getCipher = (id, context) =>
            {
                switch (context)
                {
                case CipherContext.RC_CLIENT_SESSION: return(_sessionCipher);

                case CipherContext.RSA_AUTH: return(AuthKey);

                default: return(null);
                }
            };

            _group        = new MultithreadEventLoopGroup();
            _scertHandler = new ScertServerHandler();

            // Initialize on connect
            _scertHandler.OnChannelActive += async(channel) =>
            {
                RecvQueue.Clear();
                SendQueue.Clear();
                State = ClientState.CONNECTED;

                await OnConnected(channel);
            };

            //
            _scertHandler.OnChannelInactive += async(channel) =>
            {
                await OnDisconnected(channel);
            };

            // Queue all incoming messages
            _scertHandler.OnChannelMessage += (channel, message) =>
            {
                RecvQueue.Enqueue(message);

                // Log if id is set
                if (message.CanLog())
                {
                    Logger.Info($"RECV {channel}: {message}");
                }
            };

            try
            {
                var bootstrap = new Bootstrap();
                bootstrap
                .Group(_group)
                .Channel <TcpSocketChannel>()
                .Option(ChannelOption.TcpNodelay, true)
                .Handler(new ActionChannelInitializer <ISocketChannel>(channel =>
                {
                    IChannelPipeline pipeline = channel.Pipeline;

                    pipeline.AddLast(new ScertEncoder());
                    pipeline.AddLast(new ScertIEnumerableEncoder());
                    pipeline.AddLast(new ScertTcpFrameDecoder(DotNetty.Buffers.ByteOrder.LittleEndian, Constants.MEDIUS_MESSAGE_MAXLEN, 1, 2, 0, 0, false));
                    pipeline.AddLast(new ScertDecoder(_sessionCipher, AuthKey));
                    pipeline.AddLast(_scertHandler);
                }));

                try
                {
                    _boundChannel = await bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(serverIp), serverPort));
                }
                catch (Exception e)
                {
                    Logger.Error($"Failed to connect to server {e}");
                    State = ClientState.DISCONNECTED;
                    return;
                }
            }
            finally
            {
            }
        }