HomeServer/lualib-src/Server-main/Lib/Tcp/TcpSocket.lua
2024-11-20 15:41:37 +08:00

129 lines
3.6 KiB
Lua

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