quick-cocos2dx Socket連接若干問題總結

--
-- 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小於等於新的包的長度,那麼就可以調用處理包的邏輯,進行處理了。







發佈了79 篇原創文章 · 獲贊 16 · 訪問量 58萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章