V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
b00tyhunt3r
V2EX  ›  程序员

TCP/UDP 服务器怎么实现 request handler?

  •  
  •   b00tyhunt3r · 2022-07-05 13:36:47 +08:00 · 2594 次点击
    这是一个创建于 854 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人只做过传统的 restful API web server, 客户端请求通过路由传给不同的 API handler ,实现各种功能, 如果是 TCP/UDP 服务器的情况下,要怎么实现这个路由给 handler 的功能呢?

    举个例子,游戏服务器, 传统 restful 的情况下比如有一个查询人物等级的 api ,另有一个更新人物属性的 api 通过路由 api/level 和 api/stat 交由各自的 handler 处理

    但在 tcp/udp 的情况下,似乎本来就不存在路由或者 handler 这个概念?那要怎么处理类似情况呢?

    24 条回复    2022-07-06 10:26:39 +08:00
    iBugOne
        1
    iBugOne  
       2022-07-05 13:41:58 +08:00 via Android
    TCP/UDP 和 HTTP 就不在同一层,如果你要 TCP 服务器的话就要自己设计数据报格式,自己解析然后“路由”。

    这就好比自己设计二进制游戏存档格式,不用 JSON/XML 但是又想用 jsonpath/xpath 来找数据一样
    FrankAdler
        2
    FrankAdler  
       2022-07-05 13:42:52 +08:00
    我先不说所谓的答案,尝试引导下你:你了解过 http 协议吗,或者说怎样的数据才能别识别撑 http ,要实现一个 http 路由依赖哪些东西?
    dogepy
        3
    dogepy  
       2022-07-05 13:43:52 +08:00 via Android
    rpc
    swat199538
        4
    swat199538  
       2022-07-05 13:44:16 +08:00
    TCP/UDP 是传输层协议,不关心你应用层怎么解析数据。自己定义
    frank1256
        5
    frank1256  
       2022-07-05 13:44:17 +08:00
    你的问题好比在问,不用 HTTP 怎么接发请求。当然自定义协议哇。
    nothingistrue
        6
    nothingistrue  
       2022-07-05 13:46:19 +08:00
    你说的这个 request handler ,传输层用得还是 TCP ,它只是应用层用的 http 协议 。你自己的服务器,并不是直接运行在 TCP/UDP 协议上的,它也需要有专门的应用层协议。你照着 http 协议,搞一个带路由功能的协议即可。单纯的协议可能很难,但是要是把协议跟你开发用的工具结合起来定义,应该会很简单。
    newmlp
        7
    newmlp  
       2022-07-05 13:51:12 +08:00
    不想折腾就上 rpc ,或者自研 rpc
    neoblackcap
        8
    neoblackcap  
       2022-07-05 13:57:10 +08:00
    TCP/UDP 只是传输层协议,真正在用的时候会定义应用层的协议。那么应用层协议就对应 http 协议了。类似应用层就可以解析出一些关键字段,然后根据路由跳转。
    当然了,一般都是直接用 rpc 框架来实现这些。一般情况下,开发者压根不用管路由。
    xiaxiaokang
        9
    xiaxiaokang  
       2022-07-05 14:04:56 +08:00
    你买了一组乐高,你会让顺丰快递把你拆包搭建好给你么?
    1.TCP 和 UDP 是传输协议,负责包裹是否有破损或丢包,UDP 丢包全部重新发,少了检查完整性所以效率比 TCP 高
    2.request handler 属于 HTTP 协议,具体查看 HTTP 协议格式,里面带了 method ,path,header .......
    yolee599
        10
    yolee599  
       2022-07-05 15:56:41 +08:00
    这个是应用层要考虑的事情,TCP/UDP 就是一条公路,你把货物运到哪里完全由你自己决定。
    server
        11
    server  
       2022-07-05 16:07:32 +08:00
    tlv, 自己定协议处理
    swulling
        12
    swulling  
       2022-07-05 16:23:22 +08:00
    自己设计一套应用层协议就可以了。最简单的就是在包头增加一个 COMMAND 。

    这个协议简单可以很简单,复杂也可以像 http 那么复杂。

    最简单的一种协议大概是这个样子:

    | 标识(约定一个固定长度,如 4B ) | Length(4B) | Command(4B) | Content ( xxxxx B )

    写个接收逻辑,收到特定的标识后,读出整个指令(长度从 Length 中读取),然后根据 Command 转发给对应的方法处理即可。

    之前做单片机做串口通信的时候,协议就是自己实现的,也没啥难度。代码量很少。
    lazyfighter
        13
    lazyfighter  
       2022-07-05 16:23:38 +08:00
    估计 servlet 都不知道,spring 基础也不合格,springmvc 的 dispatcherServlet 估计也不知道
    swulling
        14
    swulling  
       2022-07-05 16:24:29 +08:00
    @swulling 一般最后再增加一个 校验码,对整个 Payload 进行一次异或 或 CRC32 之类的校验,避免传输错误。
    Trim21
        15
    Trim21  
       2022-07-05 16:38:47 +08:00 via Android
    重新发明 HTTP (
    janxin
        16
    janxin  
       2022-07-05 16:40:59 +08:00
    协议解析->协议 handler
    DeepRedApple
        17
    DeepRedApple  
       2022-07-05 16:49:11 +08:00
    Netty 使用 TLV 格式的数据包就很容易解决这个问题
    hankai17
        18
    hankai17  
       2022-07-05 16:52:35 +08:00
    黏包警察在此
    ComTNT
        19
    ComTNT  
       2022-07-05 17:05:29 +08:00
    protobuf
    charlie21
        20
    charlie21  
       2022-07-05 17:31:31 +08:00 via iPhone
    难道这就是没有网游开发经验但强行答题的样子?
    xuboying
        21
    xuboying  
       2022-07-05 17:35:31 +08:00
    grpc 是当今的标准答案么?
    kekxv
        22
    kekxv  
       2022-07-05 18:30:42 +08:00 via iPhone
    试试?[kInteractiveProtocol 协议]( https://kekxv.github.io/2022/04/08/kInteractiveProtocol%20 协议 /)
    fakeshadow
        23
    fakeshadow  
       2022-07-05 18:58:39 +08:00
    最简单的可以用 length delimiter 来区分消息类型,tcp 需要额外做一下 framing ,然后回调处理即可。
    tramm
        24
    tramm  
       2022-07-06 10:26:39 +08:00
    网游不知道, 但我们的物联网私有 TCP 协议这边, 是服务器根据协议解析后, 根据不同的指令 RPC 调用不同的服务
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3176 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:44 · PVG 20:44 · LAX 04:44 · JFK 07:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.