-- Author:
-- Date: 2015-04-26 10:53:55
--
SocketMessage = {}
net = require("framework.cc.net.init")
cc.utils = require("framework.cc.utils.init")
index10001 = 1
local isConnected = false --是否已建立连接
local isConnecting = false --是否真正建立连接
local isInited = false --是否初始化过连接
-- 消息体长度占4个字节
SocketMessage.BODY_LEN = 4
local ip = nil
local port = nil
-- 数据缓存
local buf = cc.utils.ByteArrayVarint.new(cc.utils.ByteArrayVarint.ENDIAN_BIG)
function SocketMessage:init()
local time = net.SocketTCP.getTime()
print("socket time:" .. time)
local socket = net.SocketTCP.new()
socket:setName("SocketTcp")
socket:setTickTime(0.001)
socket:setReconnTime(6)
socket:setConnFailTime(4)
print("version is "..net.SocketTCP._VERSION)
net.SocketTCP._DEBUG = true
socket:addEventListener(net.SocketTCP.EVENT_DATA,handler(self,self.tcpData))
socket:addEventListener(net.SocketTCP.EVENT_CLOSE,self.tcpClose))
socket:addEventListener(net.SocketTCP.EVENT_CLOSED,self.tcpClosed))
socket:addEventListener(net.SocketTCP.EVENT_CONNECTED,self.tcpConnected))
socket:addEventListener(net.SocketTCP.EVENT_CONNECT_FAILURE,self.tcpConnectedFail))
self.socket_ = socket
end
function SocketMessage:Connect(_ip,_port)
print(" SocketMessage:Connect! ")
isConnecting = true
if isInited == false then --
isInited = true
self:init()
end
ip = _ip
port = _port
print(" 开始建立socket连接 ")
self.socket_:connect(ip,port,true)
end
--type 消息类型
function SocketMessage:SendSokcetData(_data,type)
-- local s = json.encode(_data)
-- if Globe_print then
-- print("发送消息" .. _data["cmd"] .. "==具体参数" ..s) -- for test lz
-- end
local c_byte = cc.utils.ByteArray.new(cc.utils.ByteArrayVarint.ENDIAN_BIG)
c_byte:writeStringBytes(_data)
c_byte:setPos(1)
local content_len = c_byte:getAvailable()
print(" the content_len is "..content_len)
local msg_byte = cc.utils.ByteArray.new(cc.utils.ByteArrayVarint.ENDIAN_BIG)
-- msg_byte:writeUInt(content_len)
msg_byte:writeUShort(content_len+4)
msg_byte:writeUShort(type)
msg_byte:writeStringBytes(_data)
-- msg_byte:writeString(s)
-- msg_byte:setPos(1)
print("发送数据 _dada is ".._data)
if self.socket_.isConnected then --
-- self.socket_:send(_data)
-- self.socket_:send(msg_byte:getPack(1,msg_byte:getAvailable()))
self.socket_:send(msg_byte:getPack())
print(" the pack is "..msg_byte:getPack())
else
print("socket 已经断开,正在重新连接! ")
self.socket_:connect(ip,true)
end
end
function SocketMessage:CloseSocket()
if self.socket_.isConnected then
self.socket_:close()
end
end
function SocketMessage.getBaseBA()
return cc.utils.ByteArrayVarint.new(cc.utils.ByteArrayVarint.ENDIAN_BIG)
end
local function _tick(msg)
local __msgs = {}
print("buf len is "..buf:getLen())
buf:setPos(buf:getLen()+1)
buf:writeBuf(msg)
buf:setPos(1)
local bodyLen = buf:readUShort()
print("bodyLen length is "..bodyLen)
local len2 = buf:readUShort()
print(" the data type is "..len2)
if buf:getAvailable() < bodyLen-4 then
buf:setPos(buf:getPos() - SocketMessage.BODY_LEN)
break
end
print(" the data is "..buf:readStringBytes(bodyLen-4))
local len3 = buf:getAvailable()
print(" the data len3 is "..len3)
-- __msgs[#__msgs+1] = buf:readStringBytes(bodyLen)
end
if buf:getAvailable() <= 0 then
buf = SocketMessage.getBaseBA()
else
local __tmp = SocketMessage.getBaseBA()
buf:readBytes(__tmp,1,buf:getAvailable())
buf = __tmp
end
return __msgs
end
function SocketMessage:tcpData(event)
local msgs = _tick(event.data)
print_lua_table(msgs)
if event.data ~= nil then
-- print("接收到的数据 data is "..event.data)
-- local data = cjson.decode(event.data)
-- if conditions then
-- --todo
-- end
-- Event_dispatchEvent(data.cmd,data)
else
print(" SocketMessage:tcpData is nil")
end
end
function SocketMessage:tcpClose()
print(" socket连接已经关闭! ")
end
function SocketMessage:tcpConnected()
print(" socket连接建立成功! ")
self:SendSokcetData("1",1000)
end
function SocketMessage:tcpConnectedFail()
print(" socket连接已经断开! ")
end
function SocketMessage:onExit()
if self.socket_.isConnected then
self.socket_:close()
end
self.socket_:disconnect()
end
return SocketMessage
quick-cocos2dx中使用socketTCP这个类,这个是zengrong写的。
1.读取socket的规则是*a,*a的规则是有多少读取多少,没有最大值
2.有一个tick_time,这个时候,是程序获取socket内读取到多少东西的时间间隔,这个时间间隔一般设置1秒
3.socket通信,使用的是.ByteArray的数据,需要处理粘包和半包,这两个问题
粘包的意思就是一次socket通信,同时发送了2个消息。客户端的表现就是获取的event.data中含有两个消息。
客户端的处理就是对每一个消息分别进行处理,这个比较简单。
半包的意思就是一次socket通信,只发送了部分消息。客户端的表现就是获取的event.data中消息的len包含的长度大于包的长度,
这个时候,这个包就没有收全,这个时候,不能调用解析处理包的逻辑。需要等待下次数据,把下次socket获取的数据加入到这部分消息的buf中,
然后,如果len小于等于新的包的长度,那么就可以调用处理包的逻辑,进行处理了。