Quick-Cocos2d-X + SocketTCP

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


scnet = {}


-- 初始化网络   网络监听
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


-- 发送数据 msgid 消息id,data 消息数据
function scnet.send( msgid,data )
	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
	-- 构造新的字节发送给服务器
	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来确定数据格式
function scnet.encodeData( msgid,data )
	if msgid then
		local ba = ByteArray.new(ByteArray.ENDIAN_BIG)
		local fmt = InfoUtil:getMsgFmt(msgid)
		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


-- 接收数据
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

-- 消息解析
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

-- 根据格式解析数据
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
-- 数据解密
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


    

--  发送
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 = class("NetManager")


local port = 8080
local host = "192.168.1.28"

-- 初始化
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:removeAllMsg(  )
	self._listenerList = nil
	self._listenerList = {}
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


    

function MainScene:onEnter()
  -- 添加消息事件监听
	NetManager:registerMsg(MsgType.SC_LOGIN ,handler(self,self.receiveHandler))
	
	-- test 发送事件
	-- 构造根据消息格式构造数据
	local data = {}
 		data.list = {}
 		table.insert(data.list,{id = 1001,name = "小房",level = 1,sex = 1})
 		table.insert(data.list,{id = 1002,name = "1111",level = 11,sex = 2})
 		table.insert(data.list,{id = 1003,name = "2222",level = 21,sex = 3})
 		table.insert(data.list,{id = 1004,name = "3333",level = 31,sex = 2})
 		data.userid = 10001
 		NetManager:sendMsg(MsgType.CS_LOGIN,data)
	
end

function MainScene:onExit()
  -- 移除消息事件监听
  NetManager:removeRegister(MsgType.SC_LOGIN ,handler(self,self.receiveHandler))
end


你可能感兴趣的:(Quick-Cocos2d-X + SocketTCP)