zoukankan      html  css  js  c++  java
  • Quick-cocos2d-x v3.3 SocketTCP链接(转)

    Quick-Cocos2d-x v3.3里面提供了两种长连接WebSockets、SocketTCP,这里说一下SocketTCP的用法。

    1
    2
    3
    local net = require("framework.cc.net.init")
    local ByteArray = require("framework.cc.utils.ByteArray")
    require("framework.cc.utils.bit")

    -- 网络初始化,添加侦听函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function scnet.init(  )
    local time = net.SocketTCP.getTime()
    print("socket time:" .. time)
      
    local socket = net.SocketTCP.new()
    socket:setName("HeroGameTcp")
    socket:setTickTime(1)
    socket:setReconnTime(6)
    socket:setConnFailTime(4)
    socket:addEventListener(net.SocketTCP.EVENT_DATA, scnet.receive)
    socket:addEventListener(net.SocketTCP.EVENT_CLOSE, scnet.tcpClose)
    socket:addEventListener(net.SocketTCP.EVENT_CLOSED, scnet.tcpClosed)
    socket:addEventListener(net.SocketTCP.EVENT_CONNECTED, scnet.tcpConnected)
    socket:addEventListener(net.SocketTCP.EVENT_CONNECT_FAILURE, scnet.error)
    scnet.socket = socket
    end

    --发送数据给服务器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    function scnet.send( msgid,data )
     --  encodeData 此方法是根据需要发送的数据安装与服务器定义好的消息格式去write
     local _ba = scnet.encodeData(msgid,data)
     print("scnet.send _ba",_ba:getLen())
     if not _ba then 
     print("发送数据出错了.......",msgid)
       return 
     end
     _ba:setPos(1)
     local byteList = {}
     local byteCount = 0
     --  把数据读出来,加密
     for i=1,#_ba._buf do
     local tmpBit = string.byte(_ba:readRawByte())
     byteCount = byteCount + tmpBit
     tmpBit = bit.band(tmpBit + 80,255)
     tmpBit = bit.band(bit.bnot(bit.band(tmpBit,255)),255)
     byteList<i> = tmpBit
     end
     byteCount = byteCount % 256
     -- 最后再组成一个新的ByteArray
     local result = ByteArray.new(ByteArray.ENDIAN_BIG)
     result:writeShort(_ba:getLen() + 3)
     result:writeByte(byteCount)
     for i=1,#byteList do
     result:writeByte(byteList<i>)
     end
     -- 把数据发送给服务器
     scnet.socket:send(result:getPack())
    end

     -- 根据messageid来确定数据格式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function scnet.encodeData( msgid,data )
     if msgid then
     local ba = ByteArray.new(ByteArray.ENDIAN_BIG)
     local fmt = InfoUtil:getMsgFmt(msgid)  -- 此处为读取消息格式 看下面的MessageType里面会有定义
     ba:writeStringUShort("token")  -- 此处为用户token,没有就为"",此处可以判断用户是否重新登陆啊等等.......
     for i=1,#fmt do
     scnet.writeData(ba,fmt<i>,data)
     end
     local baLength = ba:getLen()
     local bt = ByteArray.new(ByteArray.ENDIAN_BIG)
     bt:writeShort(baLength + 4)   -- 2为message length  2为message type
     bt:writeShort(msgid)
     bt:writeBytes(ba)
     return bt
     end
    end

      

    -- write 数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    function scnet.writeData( ba,msg_type,data )
       
     local key = msg_type.key
     print("scnet.writeData","key",key)
     if key and data[key] then
     local _type = msg_type["fmt"]
     if type(_type) == "string" then
     if _type == "string" then
     ba:writeStringUShort(data[key])
     elseif _type == "number" then
     ba:writeLuaNumber(data[key])
     elseif _type == "int" then
     ba:writeInt(data[key])
     elseif _type == "short" then
     ba:writeShort(data[key])
     end
     else
     ba:writeShort(#data[key])
     for k,v in pairs(data[key]) do
     for i=1,#_type do
     scnet.writeData(ba,_type<i>,v)
     end
     end
     end
     else
     print("找不到对应的 key",msg_type.key,msg_type,data)
     end
    end

    -- 读取数据

    -- 接收消息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function scnet.receive( event )
     local ba = ByteArray.new(ByteArray.ENDIAN_BIG)
     ba:writeBuf(event.data)
     ba:setPos(1)
    --  有连包的情况,所以要读取数据
     while ba:getAvailable() <= ba:getLen() do 
     scnet.decodeData(ba)
     if ba:getAvailable() == 0 then
     break
     end
     end
    end

    -- 消息数据解析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    function scnet.decodeData( ba )
     local len = ba:readShort() -- 读数据总长度
     local total = ba:readByte() -- 一个用于验证的数子
     local byteList = {}
     local tmpTotal = 0
     for i=1,len - 3 do  -- 去除前两个长度
     local tmpBit = ba:readByte()
     local enByte = scnet.decodeByte(tmpBit)
     tmpTotal = tmpTotal + enByte
     byteList<i> = enByte
     end
      
      
     local result = ByteArray.new(ByteArray.ENDIAN_BIG)
     for i=1,#byteList do
     result:writeRawByte(string.char(byteList<i>))
     end
     result:setPos(1)
     if (tmpTotal % 256) == total then
     scnet.decodeMsg(result)
     else
     print("scnet.decodeData  total   error")
     end
    end

    -- 根据格式解析数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    function scnet.decodeMsg( byteArray )
     local rData = {}
     local len = byteArray:readShort()
     local msgid = byteArray:readShort()
     local roleString = byteArray:readStringUShort()
     local fmt = InfoUtil:getMsgFmt(msgid)
     for i=1,#fmt do
     scnet.readData(byteArray,fmt<i>,rData)
     end
     if rData["result"] ~= 0 then
     print("result  handler is here  ",rData[key])
     return
     else
     NetManager:receiveMsg(msgid,rData)
     end
    end
    -- readData
    function scnet.readData( ba,msg_type,data)
     local key = msg_type.key
     if key then
     data[key] = data[key] or {}
     local _type = msg_type["fmt"]
     if type(_type) == "string" then
     if _type == "string" then
     data[key] = ba:readStringUShort()
     elseif _type == "number" then
     data[key] = ba:readLuaNumber()
     elseif _type == "int" then
     data[key] = ba:readInt()
     elseif _type == "short" then
     data[key] = ba:readShort()
     end
      
      
     if key == "result" then  -- 当结果不为零的时候,说明有错误
       
     if data[key] ~= 0 then
     print("result  handler is here  ",data[key])
     return
     end
     end
      
      
     else
     local _len = ba:readShort() -- 读取数组长度
     for i=1,_len do
     local tmp = {}
     for j=1,#_type do
     scnet.readData(ba,_type[j],tmp)
     end
     table.insert(data[key],tmp)
     end
       
     end
     else
     print("找不到对应的 key  scnet.readData",msg_type.key,msg_type,data)
     end
    end

    -- 数据解密

    1
    2
    3
    4
    5
    function scnet.decodeByte( byte )
     local tmp = bit.band(bit.bnot(bit.band(byte,255)),255)
     tmp = bit.band((tmp + 256 - 80),255)
     return tmp
    end

    消息格式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    -- 发送
    MsgFmt["1001"] = {
     {
     key = "list",
     fmt = {
     
     key = "id",fmt = "int"
     },
     
     key = "name",fmt = "string"
     },
     
     key = "level",fmt = "int"
     },
     
     key = "sex",fmt = "int"
     }
     }
     },
     {
     key = "userid",fmt = "int"
     }
    }
    --  返回
    MsgFmt["5001"] = {
     {
     key = "result",fmt = "int" 
     },
     {
     key = "list",
     fmt = {
     
     key = "id",fmt = "int"
     },
     
     key = "name",fmt = "string"
     },
     
     key = "level",fmt = "int"
     },
     
     key = "sex",fmt = "int"
     }
     }
     }
    }

    网络管理NetManager

    管理网络的发送与接收

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    -- 初始化
    function NetManager:init(  )
     self._listenerList = {}
     scnet.init()
     scnet.connect(host,port)
    end
      
    -- 注册消息
    -- 注册之后 接受到服务器消息之后进行广播,谁注册,谁相应
    function NetManager:registerMsg( msgid,callBack )
     self._listenerList[msgid] = self._listenerList[msgid] or {}
     local isExist = self:findCallBack(msgid,callBack)
     if not isExist then
     table.insert(self._listenerList[msgid],callBack)
     end
    end
      
      
      
    -- 移除注册消息
    function NetManager:removeRegister( msgid,callBack )
     if self._listenerList[msgid] then
     for k,v in pairs(self._listenerList) do
     if v == callBack then
     self._listenerList[msgid][k] = nil
     end
     end
     end
    end
      
      
      
    -- 发送消息
    -- 整理数据发送给服务器
    function NetManager:sendMsg( msgid,data )
     scnet.send(msgid,data)
    end
      
      
      
    -- 接受消息
    -- 派发事件(数据)
    function NetManager:receiveMsg( msgid,data )
     if self._listenerList[msgid] then
     for k,v in pairs(self._listenerList[msgid]) do
     v(data)
     end
     end
    end
      
      
    function NetManager:findCallBack( msgid,callBack )
     for k,v in pairs(self._listenerList[msgid]) do
     if v == callBack then
     return true
     end
     end
     return false
    end

      

    test

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    -- 监听事件
    function MainScene:onEnter()
     NetManager:registerMsg(MsgType.SC_LOGIN ,handler(self,self.receiveHandler))
    end
      
    -- 移除坚挺
    function MainScene:onExit()
        NetManager:removeRegister(MsgType.SC_LOGIN ,handler(self,self.receiveHandler))
    end
     
    -- 发送数据,根据MsgFmt构造数据
     local data = {}
      data.list = {}
      table.insert(data.list,{id = 1001,name = "小房",level = 1,sex = 1})
      table.insert(data.list,{id = 1002,name = "小田",level = 11,sex = 2})
      table.insert(data.list,{id = 1003,name = "2222",level = 21,sex = 1})
      table.insert(data.list,{id = 1004,name = "3333",level = 31,sex = 2})
      data.userid = 10001
      NetManager:sendMsg(MsgType.CS_LOGIN,data)

     

    http://cn.cocos2d-x.org/tutorial/show?id=2604

    http://zengrong.net/post/2020.htm

  • 相关阅读:
    DOM型XSS(pikachu)
    第十周笔记
    第九周数据结构
    第八周数据结构笔记
    第七周笔记
    第六周笔记
    第五周数据结构
    第四周笔记
    数据结构(第三周)
    数据结构—第二周学习笔记
  • 原文地址:https://www.cnblogs.com/zhangfeitao/p/4505425.html
Copyright © 2011-2022 走看看