jintiao / sproto-cs

Sproto in c#
21 stars 8 forks source link

Invalid unpack stream #4

Closed puXiaoyi closed 9 years ago

puXiaoyi commented 9 years ago

你好,这两天使用你的开源项目sproto_cs写客户端,遇到一些问题百思不得其解,望指点迷津。

服务器是在你的项目 some_mmorpg上稍作改动重写的,协议如下。

local server_proto = sproto.parse [[ .package { type 0 : integer session 1 : integer }

handshake 1 { request { name 0 : string
client_pub 1 : string
} response { result 0 : integer
server_pub 1 : string
challenge 2 : string
} }

auth 2 { request { challenge 0 : string
password 1 : string
} response { session 0 : integer
challenge 1 : string
} }

chap 3 { request { session 0 : integer
challenge 1 : string
} response { token 0 : string
challenge 1 : string
} }

login 4 { request { session 0 : integer
token 1 : string
} }

]]

local client_proto = sproto.parse[[ .package { type 0 : integer session 1 : integer } ]]

/// <summary>
/// login request
/// </summary>
/// <param name="Arg">dispatch result.Arg</param>
private void Login(SpObject Arg)
{
    if (null != Arg)
    {
        //read value from Arg
        String token = Arg["token"].Value.ToString();

        String challenge = Arg["challenge"].Value.ToString();

        //use secert to encrypt token
        byte[] token_code = Convert.FromBase64String(token);

        byte[] desencode_token_code = DES.Encode(secret_code, token_code);

        //token = Convert.ToBase64String(desencode_token_code);
        token = "AEPIDA1uhEo9d3Bo1pP85g==";

        //send sproto package
        Send("login", new SpObject(SpObject.ArgType.Table,
                               "session", session,
                               "token", token));
    }
}

在最后login的request中,我发送 经过des加密的base64 token串,服务器总是提示 [:00000015] [gamed] nil login failed : ../3rd/skynet/lualib/sproto.lua:179: Invalid unpack stream stack traceback: [C]: in function 'sproto.unpack' ../3rd/skynet/lualib/sproto.lua:179: in method 'dispatch' ./lualib/gameserver/gameserver.lua:57: in function <./lualib/gameserver/gameserver.lua:52> [C]: in function 'xpcall' ./lualib/gameserver/gameserver.lua:77: in field 'message' ./lualib/gameserver/gateserver.lua:110: in function <./lualib/gameserver/gateserver.lua:104> (...tail calls...) ../3rd/skynet/lualib/skynet.lua:110: in function <../3rd/skynet/lualib/skynet.lua:104>

于是我去掉token随机,写死成其中一次的token串 AEPIDA1uhEo9d3Bo1pP85g==,打印mSendStream.Buffer 如下 0,35,85,2,10,10,2,17,1,24,255,2,65,69,80,73,68,65,49,117,104,69,111,57,100,51,66,111,49,112,80,56,53,103,61

尝试 把token串 增加或减少 一个字符,服务器sproto.unpack都不会报错,并且能正确解析 怀疑是串的问题,所以尝试把 auth request 的challenge 改成相同的串,程序运行正常,但是把 chap request的challenge 修改则 也报 Invalid unpack stream的错误。

在云风的sproto项目的testrpc.lua中修改测试,local req = client_request("login", { token = "AEPIDA1uhEo9d3Bo1pP85g==" }, 1) 打印的req字节流85,2,10,4,2,17,1,24,255,2,65,69,80,73,68,65,49,117,104,69,111,57,100,51,66,111,49,112,80,56,53,103,61,61 和mSendStream.Buffer中的字节流不一样,因为二者的编解码、打解包,虽然看过但是没有太明白。测试了一下,两边都正常时字节流也不一样。 但是server:dispatch(req)是正常执行的,输出的request打印是 token [AEPIDA1uhEo9d3Bo1pP85g==]

我又把req = string.char(85,2,10,10,2,17,1,24,255,2,65,69,80,73,68,65,49,117,104,69,111,57,100,51,66,111,49,112,80,56,53,103,61) 如果这样把mSendStream.Buffer里去掉头两位放进去写死,server:dispatch(req)也是报 Invalid unpack stream的错误。

奇怪的是,如果末尾再加一位 61,req = string.char(85,2,10,10,2,17,1,24,255,2,65,69,80,73,68,65,49,117,104,69,111,57,100,51,66,111,49,112,80,56,53,103,61,61) server:dispatch(req)输出的request打印居然是 token [AEPIDA1uhEo9d3Bo1pP85g==]

不好意思,说了这么多,希望你能抽点时间给我指正,现在公司的项目准备使用skynet+U3d,刚开始摸索遇到很多问题, 学习你的开源项目受益匪浅,真诚谢谢你的无私分享!

jintiao commented 9 years ago

hi, 旧版本对string的pack有些问题,请pull一下最新的代码,希望能修复这个bug。

jintiao commented 9 years ago

应该是fixed了