Beispiel #1
0
        public void DispatchPacket(NetPacket pkt)
        {
            pkt.ReadData();
            ushort        cmdid   = pkt.GetCmdId();
            PacketSession session = pkt.GetSession();
            object        data    = pkt.GetData();

            _NetPackDispathcer.EventDispatch(cmdid, data);

#if HKMM_DEV
            if (data is CommonRsp)
            {
                var rsp = data as CommonRsp;
                if (!rsp.Success)
                {
                    Debug.Log(rsp.ErrorStr);
                }
            }
#endif

            if (session.PType == PacketSession.Types.PacketType.Response)
            {
                try
                {
                    _waitResponse.Remove((ushort)session.CmdId);
                    _cacheCallback[session.SessionId](data);
                    _cacheCallback.Remove(session.SessionId);
                }
                catch (Exception e)
                {
                    SuperDebug.Error(e.ToString());
                }
            }
        }
Beispiel #2
0
        public void ReadData()
        {
            try
            {
                _bodyMem.Position = 0;
                byte[] numberBytes = new byte[4];

                _bodyMem.Read(numberBytes, 0, NetDefine.CMD_BYTES);
                _cmdId = NetUtils.BigEndianToUshort(numberBytes);

                _bodyMem.Read(numberBytes, 0, NetDefine.SESSION_LEN_BYTES);
                ushort sessionLen = NetUtils.BigEndianToUshort(numberBytes);
                _bodyMem.Read(numberBytes, 0, NetDefine.CONTENT_LEN_BYTES);
                uint contentLen = NetUtils.BigEndianToUint(numberBytes);

                byte[] sessionBytes = new byte[sessionLen];
                _bodyMem.Read(sessionBytes, 0, sessionLen);

                _sessionMem.Write(sessionBytes, 0, sessionLen);
                _sessionMem.Position = 0;

                _session = PacketSession.Parser.ParseFrom(_sessionMem);

                _content = CommandMap.Instance.GetMessageByCmdId(_cmdId);
                _content.MergeFrom(_bodyMem);
            }
            catch (System.Exception e)
            {
                SuperDebug.Error(DebugPrefix.Network, "Deserialize meet exception " + e);
                OutputBytes("error buf:", _bodyMem.GetBuffer(), _bodyMem.Length);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Use this function carefully, because it may return 'null'.
        /// </summary>
        /// <param name="propCal"></param>
        /// <returns></returns>
        public BaseCalculation GetCal(int propCal)
        {
            if (_calDict.ContainsKey(propCal))
            {
                return(_calDict[propCal]);
            }

            if (_GetBaseCal != null)
            {
                BaseCalculation cal = _GetBaseCal(propCal);
                if (cal != null)
                {
                    _calDict.Add(propCal, cal);
                    return(cal);
                }
            }

            SuperDebug.Error(propCal + " doesn't exist");
            return(null);
        }
Beispiel #4
0
        /*
         *  循环接受数据的线程,将收到的packet写入队列
         */
        private void ClientProducerThreadHandler()
        {
            SuperDebug.Log(DebugPrefix.Network, "clientProducer thread start.");
            while (IsConnected())
            {
                try
                {
                    List <NetPacket> list = RecvPacketList();
                    //MiLog.Log("recv " + list.Count + " packet");
                    if (null != list && 0 != list.Count)
                    {
                        foreach (NetPacket packet in list)
                        {
#if NG_HSOD_DEBUG
                            //Thread.Sleep(100);
#endif
                            lock (recv_queue_)
                            {
                                recv_queue_.Enqueue(packet);
                            }
                        }
                        timeout_event_.Set();
                    }

                    // 发送心跳包
                    KeepAlive();
                }
                catch (SystemException e)
                {
                    SuperDebug.Error(DebugPrefix.Network, e.ToString());
                }
            }
            // 断开连接
            Disconnect();
            SuperDebug.Log(DebugPrefix.Network, "clientProducer thread stop.");
        }
Beispiel #5
0
        /*
         *  建立连接
         */
        public bool Connect(string host, ushort port, int timeout_ms = 2000)         //以毫秒为单位
        {
            try
            {
                // 检查是否已经建立连接
                if (IsConnected())
                {
                    SuperDebug.Warning(DebugPrefix.Network, "client is already connected to " + host_ + ":" + port_ + ", can not connect to other server now.");
                    return(false);
                }

                // 赋值
                host_       = host;
                port_       = port;
                timeout_ms_ = timeout_ms;

                // 根据host获取ip列表
                IPAddress[] ip_list = Dns.GetHostAddresses(host_);
                if (0 == ip_list.Length)
                {
                    SuperDebug.Warning(DebugPrefix.Network, "can not get any ip address from host " + host_);
                    return(false);
                }

                // 尝试连接每个ip
                socket_         = null;
                _remoteEndPoint = null;
                for (int idx = 0; idx < ip_list.Length; idx++)
                {
                    IPAddress ip_tmp = GetIPAddress(ip_list[idx]);

                    SuperDebug.Log(DebugPrefix.Network, "try to connect to " + ip_tmp);
                    IPEndPoint ipe        = new IPEndPoint(ip_tmp, port_);
                    Socket     socket_tmp = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                    // 初始化socket属性
                    socket_tmp.NoDelay           = true;
                    socket_tmp.Blocking          = true;
                    socket_tmp.SendTimeout       = timeout_ms_;
                    socket_tmp.ReceiveTimeout    = timeout_ms_;
                    socket_tmp.ReceiveBufferSize = ClientDefine.g_recv_buf_size * 2;

                    // 连接
                    timeout_event_.Reset();
                    socket_tmp.BeginConnect(ip_tmp, port_, new AsyncCallback(ConnectCallback), socket_tmp);

                    // 超时等待连接建立
                    timeout_event_.WaitOne(timeout_ms, false);

                    // 检验连接是否成功
                    if (socket_tmp.Connected)
                    {
                        socket_         = socket_tmp;
                        _remoteEndPoint = ipe;
                        SuperDebug.Log(DebugPrefix.Network, "socket_.ReceiveBufferSize= " + socket_.ReceiveBufferSize);

                        break;
                    }
                    else
                    {
                        SuperDebug.Log(DebugPrefix.Network, "connect to " + ip_tmp + " timeout.");
                        continue;
                    }
                }

                // 检查是否成功连接
                if (null == socket_)
                {
                    SuperDebug.Warning(DebugPrefix.Network, "connect to " + host_ + ":" + port_ + " failed.");
                    return(false);
                }
                else
                {
                    SuperDebug.Log(DebugPrefix.Network, "connect to " + host_ + ":" + port_ + " succ.");
                    SuperDebug.Log(DebugPrefix.Network, "_remoteEndPoint= " + _remoteEndPoint);
                }

                // 启动工作线程
                StartClientThread();

                //
                connected_before_ = true;
            }
            catch (System.Exception e)
            {
                SuperDebug.Error(DebugPrefix.Network, "connect to " + host + ":" + port + " meet exception " + e.ToString());
                return(false);
            }

            return(true);
        }
Beispiel #6
0
        /*
         *  同步方式接受多个消息
         *      如果当前有可读消息,则立刻返回,否则超时等待设置的时间
         */
        private List <NetPacket> RecvPacketList()
        {
            // 检查连接状态
            if (!IsConnected())
            {
                SuperDebug.Warning(DebugPrefix.Network, "client is not connected, can not recv now.");
                return(null);
            }

            // 开始接受数据
            List <NetPacket> list = new List <NetPacket>();

            try
            {
                // 接受到缓存
                byte[]      recv_buf = new byte[ClientDefine.g_recv_buf_size - left_buf_len_];
                SocketError error    = new SocketError();
                int         recv_len = socket_.Receive(recv_buf, 0, recv_buf.Length, SocketFlags.None, out error);

                // 接受超时立刻返回
                if (error == SocketError.TimedOut ||
                    error == SocketError.WouldBlock ||
                    error == SocketError.IOPending)
                {
                    return(list);
                }

                // 如果接受数据长度为0,则表示连接出现异常,需要立刻使用回调函数通知使用方
                if (error != SocketError.Success || 0 == recv_len)
                {
                    SuperDebug.Warning(DebugPrefix.Network, "recv failed with recv_len=" + recv_len + ", error=" + error);
                    socket_.Close();
                    socket_ = null;
                    return(list);
                }

                // 合并上次剩余、本次收到的数据
                byte[] total_buf = new byte[ClientDefine.g_recv_buf_size];
                Array.Copy(left_buf_, 0, total_buf, 0, left_buf_len_);
                Array.Copy(recv_buf, 0, total_buf, left_buf_len_, recv_len);
                int total_len = recv_len + left_buf_len_;
                left_buf_len_ = 0;

                // 开始处理
                int used = 0;

                // 一次可能recv多个packet,循环反序列化每个packet,并加入list
                while (used < total_len)
                {
                    //缓存之前的有效数据
                    if (_tempPacket == null)
                    {
                        _tempPacket = new NetPacket();
                    }

                    PacketStatus packet_status = _tempPacket.Deserialize(ref total_buf, ref used, total_len);

                    if (PacketStatus.PACKET_CORRECT != packet_status)
                    {
                        // 存储残缺的数据
                        if (PacketStatus.PACKET_NOT_COMPLETE == packet_status)
                        {
                            left_buf_len_ = total_len - used;
                            Array.Copy(total_buf, used, left_buf_, 0, left_buf_len_);
                        }
                        else
                        {
                            SuperDebug.Warning(DebugPrefix.Network, "deserialize packet failed. " + packet_status);
                        }

                        break;
                    }
                    else
                    {
                        list.Add(_tempPacket);
                        _tempPacket = null;
                    }
                }
            }
            catch (SystemException e)
            {
                if (IsConnected())
                {
                    SuperDebug.Error(DebugPrefix.Network, "recv failed: " + e);
                }
            }
            return(list);
        }