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 = socketend |
--发送数据给服务器
|
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 endend |
-- 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) endend |
-- 读取数据
-- 接收消息
|
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 endend |
-- 消息数据解析
|
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") endend |
-- 根据格式解析数据
|
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) endend-- readDatafunction 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) endend |
-- 数据解密
|
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 tmpend |
消息格式
|
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) endend -- 移除注册消息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 endend -- 发送消息-- 整理数据发送给服务器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 endend function NetManager:findCallBack( msgid,callBack ) for k,v in pairs(self._listenerList[msgid]) do if v == callBack then return true end end return falseend |
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
Quick-cocos2d-x v3.3 SocketTCP链接(转)的更多相关文章
- 转载+自练(莫喷)怎样在cocos2d 2.1.4里面使用动画和Texture Packer
本文实践自 Ray Wenderlich.Tony Dahbura 的文章<How to Use Animations and Sprite Sheets in Cocos2D 2.X>, ...
- Cocos2D中Action的进阶使用技巧(二)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上回说到解决办法是使用CCTargetedAction类. C ...
- Google map API V3
本文主要总结Google map API V3使用中最简单也是最常见的一些操作以及相关概念,如果需要更加详细的信息,请直接阅读Google提供的关于map的文档. google map api v3文 ...
- 【Q2D】如何导出自定义C++类给框架使用
本文基于Quick cocos2d x这个游戏框架,为了行文流畅,后面都简称Q2D 导出自定义c++类给项目使用已经有了现成的例子了 详见:http://quick.cocos.org/?p=235 ...
- Sharepoint学习笔记—习题系列--70-576习题解析 -(Q52-Q55)
Question 52You are responsible for rebranding the My Sites section of a corporate SharePoint 2010 fa ...
- 嵌入式设备上的 Linux 系统开发
转载:http://www.ibm.com/developerworks/cn/linux/embed/embdev/index.html 如果您刚接触嵌入式开发,那么大量可用的引导装载程序(bo ...
- OpenStack基础组件安装keystone身份认证服务
域名解析 vim /etc/hosts 192.168.245.172 controller01 192.168.245.171 controller02 192.168.245.173 contro ...
- mui扩展字体在哪里下载
一次在一个知名前端模板网站上用积分下载了一个手机网页模板,没想到作者竟然玩起了删减隐藏,故意挖坑. 查看其原因是少一个mui.ttf的文件,纵然其他的文件及名称都有删改但无关紧要.也就是好多人搜索的m ...
- 总结界面框架_UI_Adapter
本人定期更新经典案例及解决方案如有疑问请联系我QQ1822282728 -- 277627117 下面是常用到的ui Demo 安卓三级筛选菜单listview(非常经典) http://dow ...
随机推荐
- Java基础之读文件——使用缓冲读取器读取文件(ReaderInputFromFile)
控制台程序,本例读取Java基础之写文件部分(WriterOutputToFile)写入的Saying.txt. import java.io.*; import java.nio.file.*; i ...
- LIS 最长递增子序列
一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...
- zabbix服务器监控suse系统教程
zabbix服务器监控suse系统教程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 花了近一个星期才学会了如何监控window和linux主机的基本信息以及报价情况(我已经把笔记 ...
- 20145207 《Java程序设计》第8周学习总结
前言: 这两天电路焊小车,有意思归有意思,确实挺忙的.博客到现在才写.执勤看的东西忘得好快呀,莫名的记不住.不说废话了,开始. 教材学习内容总结: 一.NIO和NIO2 1.NIO的定义 InputS ...
- javascript DOM对象
DOM简介 1.html DOM:当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model) 2.DOM操作html JS能改变页面中的所有html元素 JS能改变页 ...
- 控件ListView
ListView的简单用法,先在布局文件中添加ListView控件: 接下来修改MainActivity中的代码: 由上面的代码可以知道,数据是无法直接传递给ListView的,需要借助适配器来完成. ...
- c语言小程序
这是一个用c语言写的小程序,功能是随机输出30道100以内的四则运算,先生成两个随机数,再通过随机数确定四则运算符号,最后输出题目. #include<iostream> using na ...
- paper 71 :图像清晰化
图像清晰度是衡量图像品质优劣的标准之一,清晰的图像能给人以赏心悦目的视觉享受.长期以来,图像扫描设备和图像处理软件的开发生产厂商都很重视图像清晰度处理功能的开发,图像处理人员也在日常的实践中不断摸索出 ...
- CSS(Cascading Style Sheet,叠层样式表),作用是美化HTML网页。
CSS(Cascading Style Sheet,叠层样式表),作用是美化HTML网页. /*注释区域*/ 此为注释语法 一.样式表 (一)样式表的分类 1.内联样式表 和HTML联合显示,控 ...
- zw版【转发·台湾nvp系列Delphi例程】HALCON SetMshape
zw版[转发·台湾nvp系列Delphi例程]HALCON SetMshape procedure TForm1.FormShow(Sender: TObject);var img : HImageX ...