当前位置: 首页 > news >正文

济南手机建站价格汕头市城市建设总公司网站

济南手机建站价格,汕头市城市建设总公司网站,ui设计需要哪些技术,网络推广公司排名目录 一、服务端(Server)通信流程1. 启动监听2. 接受客户端连接3. 接收客户端数据4. 主动关闭连接 二、客户端(Client)通信流程1. 连接服务端2. 接收服务端数据3. 主动发送数据4. 断开连接 三、完整交互时序图四、关键注意事项1. …

在这里插入图片描述

目录

  • 一、服务端(Server)通信流程
    • 1. 启动监听
    • 2. 接受客户端连接
    • 3. 接收客户端数据
    • 4. 主动关闭连接
  • 二、客户端(Client)通信流程
    • 1. 连接服务端
    • 2. 接收服务端数据
    • 3. 主动发送数据
    • 4. 断开连接
  • 三、完整交互时序图
  • 四、关键注意事项
    • 1. 非阻塞与协程
    • 2. 粘包/分包处理
    • 3. 错误处理
  • 五、性能优化建议
  • 六、示例代码整合
    • 服务端完整代码
    • 客户端完整代码

以下是基于 Skynet 框架的 Socket 通信流程详解,涵盖服务端与客户端的交互全过程,包括核心 API 使用、数据收发逻辑及示例代码:


一、服务端(Server)通信流程

1. 启动监听

  • API: socket.listen(host, port, backlog)
    • 功能: 绑定 IP 和端口,开启监听。
    • 参数:
      • host: 监听地址(如 "0.0.0.0" 表示所有网卡)。
      • port: 监听端口。
      • backlog: 等待连接队列的最大长度。
    • 返回值: 监听句柄 id,用于后续操作。
local skynet = require "skynet"
local socket = require "skynet.socket"-- 启动服务端
skynet.start(function()local listen_id = socket.listen("0.0.0.0", 8888, 128)skynet.error("Server listening on port 8888")socket.start(listen_id, accept_handler)  -- 注册 accept_handler 处理新连接
end)

2. 接受客户端连接

  • API: socket.start(fd, accept_cb)
    • 功能: 将监听句柄 fd 托管给 Skynet,当有新连接时触发 accept_cb
  • 回调函数: accept_handler(fd, addr)
    • 参数:
      • fd: 新连接的客户端 Socket 句柄。
      • addr: 客户端地址(如 "127.0.0.1:12345")。
local function accept_handler(client_fd, addr)skynet.error("New client connected:", addr)socket.start(client_fd, receive_handler)  -- 注册 receive_handler 处理数据
end

3. 接收客户端数据

  • 回调函数: receive_handler(fd, data)
    • 触发条件: 当客户端发送数据时,Skynet 自动调用。
    • 参数:
      • fd: 客户端 Socket 句柄。
      • data: 收到的二进制数据(可能不完整)。
    • 注意: 需自行处理粘包/分包(参考前文的分包策略)。
local function receive_handler(client_fd, data)skynet.error("Received data from client", client_fd, ":", data)-- 示例:回显数据socket.write(client_fd, "Echo: " .. data)
end

4. 主动关闭连接

  • API: socket.close(fd)
    • 功能: 关闭指定 Socket 连接。
-- 在适当位置调用
socket.close(client_fd)

二、客户端(Client)通信流程

1. 连接服务端

  • API: socket.open(host, port)
    • 功能: 发起 TCP 连接到服务端。
    • 参数: 同 socket.listen
    • 返回值: 客户端 Socket 句柄 fd
local skynet = require "skynet"
local socket = require "skynet.socket"skynet.start(function()local server_fd = socket.open("127.0.0.1", 8888)if server_fd thenskynet.error("Connected to server")socket.start(server_fd, client_receive_handler)-- 发送数据示例socket.write(server_fd, "Hello Server!")elseskynet.error("Connection failed")end
end)

2. 接收服务端数据

  • 回调函数: client_receive_handler(fd, data)
    • 逻辑与服务端 receive_handler 类似。
local function client_receive_handler(fd, data)skynet.error("Received from server:", data)
end

3. 主动发送数据

  • API: socket.write(fd, data)
    • 功能: 向指定 Socket 写入数据。
    • 注意: 数据需为字符串格式。
socket.write(server_fd, "Another message")

4. 断开连接

  • 与服务端关闭方式相同:
    socket.close(server_fd)
    

三、完整交互时序图

  Client                  Server|                        ||--- socket.open() ---->| 建立连接|                        |--触发 accept_handler|                        ||--- socket.write() ---->| 发送数据|                        |--触发 receive_handler|<--- socket.write() ----| 服务端响应|                        ||--- socket.close() ---->| 断开连接

四、关键注意事项

1. 非阻塞与协程

  • Skynet 的 Socket 操作是非阻塞的,所有收发操作通过回调异步处理。
  • 若需同步等待数据,可在协程中使用 socket.read
    local data = socket.read(fd, len)  -- 阻塞协程直到读取 len 字节
    

2. 粘包/分包处理

  • 必须设计应用层协议(如长度前缀、分隔符)确保数据完整性。
  • 示例协议解析(长度前缀):
    -- 服务端 receive_handler 中
    local buffer = {}  -- 按 fd 存储缓冲区
    function receive_handler(fd, data)if not buffer[fd] then buffer[fd] = "" endbuffer[fd] = buffer[fd] .. datawhile true doif #buffer[fd] < 2 then break end  -- 假设长度字段为 2 字节local len = string.unpack(">I2", buffer[fd])if #buffer[fd] >= len + 2 thenlocal packet = string.sub(buffer[fd], 3, len + 2)process_packet(fd, packet)buffer[fd] = string.sub(buffer[fd], len + 3)elsebreakendend
    end
    

3. 错误处理

  • 监听或连接失败时返回 nil
  • 连接异常关闭时,回调函数的 data 参数为 nil
    function receive_handler(fd, data)if not data thenskynet.error("Connection closed by peer:", fd)socket.close(fd)returnend-- 正常处理数据
    end
    

五、性能优化建议

  1. 减少内存拷贝:

    • 使用 table 存储分片数据,最后用 table.concat 合并。
    local buffer_tbl = {}
    function receive_handler(fd, data)buffer_tbl[fd] = buffer_tbl[fd] or {}table.insert(buffer_tbl[fd], data)-- ...解析协议后清理 buffer_tbl
    end
    
  2. 连接池管理:

    • 对高频短连接场景,复用 Socket 句柄减少开销。
  3. 协议设计:

    • 优先使用二进制协议(如 string.pack/string.unpack)减少传输体积。

六、示例代码整合

服务端完整代码

local skynet = require "skynet"
local socket = require "skynet.socket"local clients = {}  -- 存储客户端 fdlocal function process_packet(fd, packet)skynet.error("Process packet from", fd, ":", packet)socket.write(fd, "ACK: " .. packet)
endlocal function receive_handler(fd, data)if not data thenskynet.error("Client disconnected:", fd)socket.close(fd)clients[fd] = nilreturnend-- 假设协议为长度前缀(2字节)if not clients[fd] thenclients[fd] = { buffer = "" }endclients[fd].buffer = clients[fd].buffer .. datawhile true doif #clients[fd].buffer < 2 then break endlocal len = string.unpack(">I2", clients[fd].buffer)if #clients[fd].buffer >= len + 2 thenlocal packet = string.sub(clients[fd].buffer, 3, len + 2)process_packet(fd, packet)clients[fd].buffer = string.sub(clients[fd].buffer, len + 3)elsebreakendend
endlocal function accept_handler(fd, addr)skynet.error("New client:", addr)clients[fd] = { buffer = "" }socket.start(fd, receive_handler)
endskynet.start(function()local listen_fd = socket.listen("0.0.0.0", 8888, 128)socket.start(listen_fd, accept_handler)skynet.error("Server started on 8888")
end)

客户端完整代码

local skynet = require "skynet"
local socket = require "skynet.socket"skynet.start(function()local fd = socket.open("127.0.0.1", 8888)if not fd thenskynet.error("Connect failed")returnendsocket.start(fd, function(fd, data)if not data thenskynet.error("Server closed")returnendskynet.error("Received:", data)end)-- 发送带长度前缀的数据包local msg = "Hello World"local len = #msglocal packed = string.pack(">I2", len) .. msgsocket.write(fd, packed)
end)

通过以上流程,可清晰理解 Skynet 中 Socket 通信的完整生命周期。实际开发中需根据业务需求调整协议解析和错误处理逻辑。

http://www.dtcms.com/a/440399.html

相关文章:

  • 公司网站建设设计公司哪家好电子版简历免费的
  • 库存网站建设定制二学一做网站
  • 魔方网站建设辽宁建设工程信息网老网站
  • 绍兴网站建设报价做微商如何引流推广怎么找客源
  • php和html5做网站国外网站素材
  • 南宁著名的网站如何做自己的游戏网站
  • 卢沟桥网站建设事件营销的方法
  • 做电商搜素材网站都是什么汾阳网架公司
  • 免建网站互联网运营
  • 海南房产网站开发网页制作和网页制作设计
  • 信息推广网站点不开的那种怎么做个人建站免费服务器
  • 英文网站建设怎么样做能支付的网站贵吗
  • 58网站 做现浇混凝土微博手机网页版入口
  • 外卖网站建设方案书个人主页怎么申请
  • 深圳做企业网站沈阳建设工程管理中心
  • 巩义移动网站建设网站服务器拒绝连接
  • 网站建设 免费视频网站怎么添加关键词 好让百度收入_ 现在网站用的是模板做的
  • termsrv!InitializeSystemTrace函数分析开启调试TraceEnable和TraceClass和TraceDebugger
  • 网站建设合同百度文库wordpress 计划表格
  • 公司域名注册网站哪个好网站建设需求分析流程图
  • FTP 概念及题目
  • 如手机网站源码软件开发专业好吗
  • 公司网站建设会计分录西安wordpress开发
  • 如何建立公司网站模块校园网络及网站建设
  • 手游网站开发客户管理系统的功能
  • 网站建设 银川南京广告公司排名前十
  • 彩票网站建设维护wordpress数据库出错
  • 网站建站的步骤网络服务平台标书
  • 自学网站建设多久wordpress 开源协议
  • 英文自助建站贸易公司网站建设方案