local skynet = require "skynet" local socket = require "skynet.socket" require "skynet.manager" local errorInfo = require "ErrorInfo" local log = require "Log" local mode , socketId , addr = ... local MaxBuffSize = 409600 --200K local function echo( socketId , addr ) socket.start(socketId) local startPos = string.find(addr,":") addr = string.sub(addr,1,startPos -1 ) local c2sData = {} local s2cData = {} c2sData.socketId = socketId c2sData.addr = addr c2sData.isConnect = true local packetSize = nil while true do --关闭玩家socket local function CloseSocket( socketId ) --客户端主动断线 socket.close(socketId) c2sData.isConnect = false skynet.call("StartServer", "lua","TcpMsg",c2sData) end --读取包大小 packetSize= socket.read(socketId,6) if not packetSize then CloseSocket( socketId ) log.info(string.format("客户端主动关闭连接 SocketId %d ", socketId )) return end packetSize = tonumber(packetSize) if not packetSize then CloseSocket( socketId ) log.info(string.format("客户端发送的包头大小异常 SocketId %d ", socketId )) return end if packetSize > MaxBuffSize or packetSize <= 0 then CloseSocket( socketId ) log.info(string.format("关闭连接 SocketId %d 数据量超过阀值 最大值 %d 或者小于等于0 当前包大小 %d", socketId , MaxBuffSize , packetSize)) return end --根据包大小读取后面的数据 c2sData.data= socket.read(socketId ,packetSize) if not c2sData.data then CloseSocket( socketId ) log.info(string.format("关闭连接 SocketId %d 包数据为空,可能客户端关闭连接", socketId)) return end --把消息转发到对应的地方处理 local s2cData,retLen = skynet.call("StartServer", "lua","TcpMsg",c2sData ) if s2cData then retLen = string.format("%06d",string.len(s2cData)) socket.write(socketId, retLen..s2cData) end end end if mode == "agent" then socketId = tonumber(socketId) skynet.start(function() skynet.fork(function() echo(socketId , addr ) skynet.exit() end) end) else local function accept(socketId , addr ) skynet.newservice(SERVICE_NAME, "agent", socketId ,addr ) end local serverIp , serverPort = ... skynet.start(function() skynet.register("TcpSocket") skynet.dispatch("lua", function (_,_, cmd, ...) local socketId , c2sData = ... local isDo,s2cData = false,{} function Do( c2sData ) s2cData.code = errorInfo.Suc if "KickUserOffline" == cmd then if socketId then socket.close( socketId ) end else --服务器向客户端发送的消息 local retLen = string.format("%06d",string.len(c2sData)) local isSuc = socket.write( socketId , retLen..c2sData ) if not isSuc then s2cData.code = errorInfo.ErrorCode.UserOffline end end return s2cData end isDo,s2cData = pcall( Do, c2sData ) local sendMsg,sendLen = 0,0 if isDo then sendMsg,sendLen = skynet.pack(s2cData) else print("TcpSocket 内部错误信息",s2cData) s2cData ={} s2cData.code = errorInfo.ErrorCode.InnerError sendMsg,sendLen = skynet.pack(s2cData) end --返回去 skynet.ret(sendMsg,sendLen) end) local socketId = socket.listen(serverIp , serverPort) print("服务器开启Tcp监听 :",serverIp , serverPort) socket.start(socketId , function(socketId, addr) print("Tcp新用户成功连接 " .. addr .. " " .. socketId) -- you have choices : -- 1. skynet.newservice("testsocket", "agent", id) -- 2. skynet.fork(echo, id) -- 3. accept(id) accept(socketId , addr ) end) end) end