quick-cocos2dx Socket连接若干问题总结

来源:互联网 发布:短域名批量生成 编辑:程序博客网 时间:2024/03/29 16:27
--
-- 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, handler(self, self.tcpClose))
socket:addEventListener(net.SocketTCP.EVENT_CLOSED, handler(self, self.tcpClosed))
socket:addEventListener(net.SocketTCP.EVENT_CONNECTED, handler(self, self.tcpConnected))
socket:addEventListener(net.SocketTCP.EVENT_CONNECT_FAILURE, handler(self, 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, port, 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)


while buf:getAvailable() >= SocketMessage.BODY_LEN do 
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小于等于新的包的长度,那么就可以调用处理包的逻辑,进行处理了。







0 0
原创粉丝点击