コード例 #1
0
ファイル: UsrLogin.cs プロジェクト: sextance/TDemo
 private static Exception ConnectNode(NodeInfo node, IProtocol p)
 {
     try
     {
         // 建立连接,注册重连函数
         p.Connect();
         byte[] data = LoginPass.GenHandShake(node.uid.ToString(), node.gameServer, node.subid, ++node.index);
         p.Send(DataPack.PackLength(data));
         data = p.Read();
         if (data.Length < 2)
         {
             DebugLogger.DebugNetworkError("Process Hand Shake Message Error: Data Length is Less Than 2");
             throw new NetworkingException((int)ErrorCode.DataError);
         }
         UInt32 code = ((UInt32)data[0] << 8) + (UInt32)data[1];
         if (code != (int)ErrorCode.Success)
         {
             DebugLogger.DebugNetworkError("Process Hand Shake Message Error: Connect Node Code is " + code);
             throw new NetworkingException((int)code);
         }
     }
     catch (Exception e)
     {
         return(e);
     }
     return(null);
 }
コード例 #2
0
ファイル: UsrLogin.cs プロジェクト: sextance/TDemo
        internal static Exception Login(string ip, int port, string account, out IProtocol p)
        {
            p = new TcpProtocol(ip, port, null);
            var cfg = new Dictionary <string, ProtocolCfg>()
            {
                { "SendBufferSize", new ProtocolCfg {
                      intElement = Const.PackageMaxLength
                  } },
                { "ReceiveBufferSize", new ProtocolCfg {
                      intElement = Const.PackageMaxLength
                  } },
                { "ReceiveTimeout", new ProtocolCfg {
                      intElement = 3000
                  } }
            };

            p.SetCfg(cfg);
            NodeInfo node = null;

            try
            {
                // 第一步建立连接
                p.Connect();
                //第二步,收到服务端发回的base64(8bytes random challenge)随机串,用于后序的握手验证//
                byte[] data = p.Read();

                //第三步 生成 8bytes 随机串 client key
                byte[] client_key = Convert.FromBase64String(Encoding.Default.GetString(data, 0, data.Length));
                data = LoginPass.GenSecretKey(data, client_key);

                //第四步,向服务端发送base64(DH-Exchange(client key)) 用于生成 secret 的 key
                p.Send(DataPack.PackLength(data));

                //第五步,收到服务端发送过来的base64(DH-Exchange(server key)) 用于生成 secret 的 key
                data = p.Read();

                //第六步,secret := DH-Secret(client key/server key)服务器和客户端都可以计算出同一个 8 字节的 secret 用来加密数据
                byte[] secret = LoginPass.GenVerifySecret(data, client_key);
                NetCrypter.setSecret(secret);

                //第七步,base64(HMAC(challenge, secret))回应服务器第一步握手的挑战码,确认握手正常
                data = LoginPass.GenFirstChallenge(client_key, secret);
                p.Send(DataPack.PackLength(data));

                //第八步,DES(secret, base64(token))使用 DES 算法,以 secret 做 key 加密传输 token,token 包含帐号信息[user,sdkid]
                data = LoginPass.GenSecretUserToken(account, secret);
                p.Send(DataPack.PackLength(data));

                //第九步,认证结果信息,前2个字节retcode 200 表示成功,只有成功才解析后续内容(base64(uid:subid)@base64(server)#base64(info))
                data = p.Read();
                node = LoginPass.ProcessLoginData(data);
                // 登陆完毕,关闭当前连接,准备连接node
                p.Close();
            }
            catch (Exception e)
            {
                return(e);
            }
            DebugLogger.Debug("login node" + node.nodeHost + node.nodePort);
            // 连接节点
            p = new TcpProtocol(node.nodeHost, node.nodePort, new ReConnect(UsrLogin.ConnectNode));
            cfg["ReceiveTimeout"] = new ProtocolCfg {
                intElement = 10000
            };
            p.SetCfg(cfg);
            p.Node = node;
            return(ConnectNode(p.Node, p));
        }