The Go Programming Language
› http://golang.org/
› Go Playground
Go Projects
› Revel Web Framework
zyxk
0.02D

golang 有什么 TCP 框架?

  •  
  •   zyxk · Aug 17, 2021 · 18001 views
    This topic created in 1905 days ago, the information mentioned may be changed or developed.
    可以管理连接, 心跳包 处理粘包等,
    web 方面的很多, tcp 的没找到,大家做 TCP 都用什么呢?
    Supplement 1  ·  Aug 17, 2021
    我要做的是 c/s , 用 net 包可以,但是连接管理, 心跳包 粘包等要自己处理,
    想问下 TCP/IP 有没有什么框架.大家都用什么..好像用 go 做这个的少吧.
    好像现在都是用 rpc 实现? 新学 golang , 没找到合适的 tcp 框架.做 client/server ,用 rpc 合适?
    Supplement 2  ·  Aug 18, 2021
    谢谢各位的回复.

    tcp 是数据流, 如果 client 连续发送消息, tcp 可能会将几个连续发送出去的请求合并成一个请求发出去,
    server 收到合并后的一个请求. 这个时候,一般就需要自己处理消息边界问题.
    使用原生 TCP 那就一定会遇到数据的粘和分这个问题吧,

    我觉得粘包和拆包的描述还是挺形象的,不然怎么形容这个现象呢.
    Supplement 3  ·  Aug 18, 2021
    我只是觉的用 golang 自带 net 包中的 tcp ,有一点点麻(tou)烦(lan),所以想找个相关的框架.

    麻烦大家别再纠结粘包了.
    118 replies  •  2023-07-03 20:01:47 +08:00
    1  2  
    ❮ ❯
    cabing
    cabing
    Aug 17, 2021
    1
    rpcx
    wellsc
    wellsc
    Aug 17, 2021 via iPhone
    2
    http?
    zyxk
    zyxk
    OP
    Aug 17, 2021
    3
    @wellsc #2 不是 我要做的是 c/s , 用 net 包可以,但是连接管理, 心跳包 粘包等要自己处理,想问下 TCP/IP 有没有什么框架.大家都用什么..好像用 go 做这个的少吧.
    noe132
    noe132
    Aug 17, 2021 via Android❤️31
    4
    粘包警察还有 5 分钟到达战场
    toma77
    toma77
    Aug 17, 2021
    5
    grequests
    zyxk
    zyxk
    OP
    Aug 17, 2021
    6
    @noe132 #4 小白听不懂啊.

    @toma77 #5 这个是 http 库吧.
    caola
    caola
    Aug 17, 2021
    7
    gopacket ?
    zyxk
    zyxk
    OP
    Aug 17, 2021
    8
    @cabing #1 谢谢,现在好像都是用 rpc 了? 到现在也也不是太懂 rpc,以为比传统的 tcp 通讯复杂,也没仔细看过.
    刚查的,是这样吗? https://www.zhihu.com/question/41189095
    lity
    lity
    Aug 17, 2021
    9
    zinx
    EIJAM
    EIJAM
    Aug 17, 2021 via iPhone
    10
    标准库
    hedwi
    hedwi
    Aug 17, 2021
    11
    grpc 简单高效
    Mohanson
    Mohanson
    Aug 17, 2021
    12
    粘包警察虽迟但到
    whwlsfb
    whwlsfb
    Aug 18, 2021 via Android
    13
    grpc,既现代又高效,跨平台、工具集完备
    zyxk
    zyxk
    OP
    Aug 18, 2021
    14
    @Mohanson #12 粘包警察虽迟但到 啥意思啊, 虽迟但到懂. 粘包警察不懂啥意思.
    lasfresas
    lasfresas
    Aug 18, 2021 via Android
    15
    @zyxk 就是有人喜欢说 tcp 黏包之类的话
    rophie123
    rophie123
    Aug 18, 2021 via iPhone
    16
    就用 net 库,做过一个项目,粘包没出现过
    hahasong
    hahasong
    Aug 18, 2021
    17
    TCP 哪来的粘包,建议重修网络原理
    SingeeKing
    SingeeKing
    Aug 18, 2021 via iPhone
    18
    @hahasong 只有 TCP 有粘包啊
    SingeeKing
    SingeeKing
    Aug 18, 2021 via iPhone
    19
    CS 架构其实也可以用 HTTP 的,如果需要双向通信可以 Websocket 。如果种种考虑不想选择 HTTP 的话,首选建议是 grpc,类似的替代方案也有 messagepack 或是 Go 自己的 gob 也
    dcoder
    dcoder
    Aug 18, 2021❤️4
    20
    TCP 哪来的粘包,建议重修网络原理 +1
    Trim21
    Trim21
    Aug 18, 2021
    21
    粘包警察虽迟但到
    allenby
    allenby
    Aug 18, 2021 via Android❤️2
    22
    TCP 哪来的粘包,建议重修网络原理 +1
    Microkernel
    Microkernel
    Aug 18, 2021
    23
    @SingeeKing 粘包警察又抓获一名自投罗网的
    catcn
    catcn
    Aug 18, 2021
    25
    leon0318
    leon0318
    Aug 18, 2021 via iPhone
    26
    流 流 流,说三遍
    ICKelin
    ICKelin
    Aug 18, 2021
    27
    golang 用 net 库处理不是很麻烦吧。
    chendy
    chendy
    Aug 18, 2021
    28
    除非 rpc 不满足需求否则就用 rpc 就好
    balabalaguguji
    balabalaguguji
    Aug 18, 2021
    29
    @leonme
    @allenby
    @dcoder
    @hahasong

    你们是没用过 TCP 吧,就是因为流,才需要处理粘包、分包问题,不懂不要乱喷,好好补补知识
    qwerthhusn
    qwerthhusn
    Aug 18, 2021
    30
    TCP/UDP 是在第三层( TCP/IP 协议栈不是 OSI )

    HTTP 是在 TCP 上面的套娃,在第四层(例外:HTTP/3 是在 UDP 上面的套娃)

    你说的那些常见 RPC 协议,要么是跟 HTTP 一样直接在 TCP/UDP 的上面。要么像 GRPC 那样直接在 HTTP 上面再套

    你甚至可以把 HTTP 当成一种 RPC 都没问题。

    所以没有必要自己基于 TCP 自创一个 RPC 协议,直接用现成成熟的就行了,像 Thrift,gRPC 这种。

    不过我建议是最最最最最简单的 HTTP 一把梭。

    如果你非要自己实现,可以使用像 go-netty 或者 getty 的这种,自己定义好 codec,然后框架会帮你处理所谓的“粘包半包”问题。
    BBCCBB
    BBCCBB
    Aug 18, 2021
    31
    gotty
    gnet

    类似 netty 的框架.
    llbgurs
    llbgurs
    Aug 18, 2021
    32
    @balabalaguguji 不懂 TCP 才会说粘包
    chenshun00
    chenshun00
    Aug 18, 2021❤️1
    33
    一群人不知道抓住个概念争论个什么,真的把 TCP 学明白了,用什么词汇都可以把这东西给人描述明白。粘拆又何妨,反正应用层能拿到完成的业务 package 。
    dacapoday
    dacapoday
    Aug 18, 2021❤️2
    34
    这么多年,就一直没搞懂这些说粘包的。难道你们协议头里没有 magic code, 没有数据包 length?
    mritd
    mritd
    Aug 18, 2021 via iPhone
    35
    drpc
    yufpga
    yufpga
    Aug 18, 2021
    36
    evio, gnet, netpoll
    zerofiny
    zerofiny
    Aug 18, 2021
    37
    https://pkg.go.dev/net 这个包? 类似 其他语言 socket api
    raptor
    raptor
    Aug 18, 2021
    38
    粘包警察的工作不到位啊,都批了这么久了,还有人以为存在“粘包”这种伪概念……

    你们以为的“粘包”是 TCP 的 feature,不懂说明你没学好

    你们会碰到“粘包”是因为你们在 TCP 之上定义的协议有问题,说明定义这个协议的人没学好
    yolee599
    yolee599
    Aug 18, 2021 via Android
    39
    @balabalaguguji 正是因为流协议所以才没有“粘包”的说法,TCP 就像一条水管,数据是源源不断流过去的,特性就是这样。TCP 会导致“粘包”这个说法是不对的,TCP 和粘包不存在因果关系
    ynkkdev
    ynkkdev
    Aug 18, 2021
    41
    gnet
    balabalaguguji
    balabalaguguji
    Aug 18, 2021
    42
    @yolee599 #39 有点扣字眼了,当然不是说流粘,说的是你发的消息变成流传输,你的多个消息粘在一起了。
    Cbdy
    Cbdy
    Aug 18, 2021 via Android
    43
    “粘包”还行
    zdt3476
    zdt3476
    Aug 18, 2021
    44
    server
    server
    Aug 18, 2021
    45
    gnet
    dreamage
    dreamage
    Aug 18, 2021
    46
    建议 #17 #18 打一架
    nmap
    nmap
    Aug 18, 2021
    47
    短短几句话就暴露了小白一个,很幼稚
    leon0318
    leon0318
    Aug 18, 2021 via iPhone
    48
    @balabalaguguji 这……算了,你继续粘包吧,培训班害死人
    ylsc633
    ylsc633
    Aug 18, 2021
    49
    看了评论我想学习学习(我只会 curd)

    可是 你们谁也不说个原理

    一方: TCP 有粘包
    一方: TCP 没有粘包

    那你们倒是说说啊...
    sunny352787
    sunny352787
    Aug 18, 2021
    50
    用 RPC 或者 websocket 吧,除了游戏已经很少看到跑裸 TCP 的了
    abersheeran
    abersheeran
    Aug 18, 2021❤️10
    52
    @ylsc633 TCP 本就是流协议,没有包的概念。如果需要划分包,一定是要在上层协议里设计长度标识位来划分包和包之间的隔离线。例如 HTTP 里的 Content-Length,Socks 里的 domain-length 等等。

    举个现实里的例子:TCP 协议就是一根水管,你拿着许多瓶矿泉水往管子对面输水,对你来说,水是一瓶瓶的,之间的区别很明显。但对于那边的人来说他只能收到一波又一波的水,至于这些水是属于哪一瓶的,他不知道。如果运气好,每一波水之间间隔也会很明显,但是这并不代表水管帮你把这些水分割了。运气不好的时候,水就连在一起下来了,这就是他们嘴里说的粘包。
    gavinandre085
    gavinandre085
    Aug 18, 2021
    53
    @ylsc633 TCP 本身协议不存在粘包说法, 数据传输中的粘包是自定协议没有定义好
    ming159
    ming159
    Aug 18, 2021❤️2
    54
    假设有一个数据源,源源不断的产生数据,需要通过 TCP 传输,同时,这些数据是一段一段的;
    假设以#开头,以$结束. 比如 #abc123$ 为一段完整数据.
    应用层代码接收到数据时,就会出现如下三种情况:
    1. 刚好收到完整的数据: #abc123$
    2. 分为了 2 次收到完整数据: 第一次: #abc ; 第二次: 123$
    3. 1 次收到数据,多于一段完整数据: #abc123$#ab

    请问你的代码如何处理以上三种情况?
    onData("#abc");
    onData("123$");
    onData("#edf456$#hj");
    onData("k789$");
    最后希望得到的是

    #abc123$
    #edf456$
    #hjk789$


    private String cache="";

    public void onData(String data){
    // 请把这里补充完整,就理解了.
    }
    ming159
    ming159
    Aug 18, 2021❤️2
    56
    @leonme
    @raptor
    @allenby
    @dcoder
    @hahasong
    @lasfresas
    "Talk is cheap ,Show me the code"
    请贴出你们针对 54 楼问题的代码
    ckdxc
    ckdxc
    Aug 18, 2021
    57
    TCP 就是 水管出水, 你用 定量 100ml 的杯子接水, 这次接 50ml, 但是每次都接满, 你要喝的时候就喝一半, 喝多少定着杯子的刻度尺就行
    goushenggege
    goushenggege
    Aug 18, 2021
    58
    双向 RPC
    zyxk
    zyxk
    OP
    Aug 18, 2021
    59
    @jlkm2010 #55 谢谢,早就发现这个 gnet 了,这个库没有发现 demo,不知道为啥.
    darknoll
    darknoll
    Aug 18, 2021
    60
    粘包是什么鬼,拿胶水粘的吗
    YuSheen1024
    YuSheen1024
    Aug 18, 2021
    61
    应用层出问题,非要怪到网络层( TCP )?
    msaionyc
    msaionyc
    Aug 18, 2021❤️3
    62
    @ming159 TCP 协议里明明白白写了:面向流。它把数据以流的形式,可靠地发送给接收方,它的事情就完美地做完了。
    你们提出的“粘包”概念是应用层自己该解决的,你们可以说,应用层的粘包问题,但说“TCP 的粘包问题”,是不严谨的
    darknoll
    darknoll
    Aug 18, 2021
    63
    @ming159 你不能直接发数据啊,你得在前面加上协议 magic number+数据长度
    ming159
    ming159
    Aug 18, 2021
    64
    @ckdxc 你说的这是一种,我没记错,应该叫做 "定长协议" ,就是一个数据段固定长度,比如 512 个字节.每次固定取这么长度的就可以.
    但是还有"可变长度"的协议,就需要在数据段中某个固定位置上指示 本次数据自身的长度,例如: #3abc,#5abcde.
    表示 #开头,随后的数字表示后续数据的长度,比如 3,5,分别表示在此之后还有若干个数据才算一段完整的数据集.

    还有另外一种,固定以回车换行符为分隔符的,无论多长,只要有回车换行符就切断
    5408
    5408
    Aug 18, 2021
    65
    这本来就是应用层的问题,你们非要往网络层扯?

    我家鸡蛋孵出来了一只鸡,但是这只鸡不会飞是什么原因?
    粘包警察:鸡蛋都没有翅膀,怎么可能会飞!
    ming159
    ming159
    Aug 18, 2021
    66
    “TCP 的粘包问题” 确实不严谨.这点我也承认.

    "基于 TCP 传输数据,必然存在应用层数据的 粘包 /拆包问题".

    如果写过 TCP 通信(Socket 编程)的懂得自然懂,不懂得说多了也没用, 可以参考 Netty 中的
    LineBasedFrameDecoder : 基于回车换行符的解码器
    DelimiterBasedFrameDecoder: 分隔符解码器,可以指定消息结束的分隔符
    FixedLengthFrameDecoder: 固定长度解码器,它能够按照指定的长度对消息进行自动解码
    LengthFieldBasedFrameDecoder :一般协议头中带有长度字段,通过使用 LengthFieldBasedFrameDecoder 传入特定的参数,来解决拆包粘包
    5408
    5408
    Aug 18, 2021❤️6
    67
    @msaionyc #62 严格来说是这样的,但是人与人沟通没必要这么抠字眼,能理解就行,就像叫人吃饭,难道就真的只吃饭不吃菜?

    楼主只是想找个在应用层可以处理粘包问题的框架,并没有将“粘包问题”甩锅给 TCP 的意思,但是为什么要抓住这个点不放呢?
    paoqi2048
    paoqi2048
    Aug 18, 2021
    68
    自己包下 net 库吧
    ming159
    ming159
    Aug 18, 2021
    69
    @darknoll 不是说所有协议都是这种模式"magic number+数据长度". 自己研究去吧
    95276
    95276
    Aug 18, 2021
    70
    @ZHanYao 因为抓不到其他的点.
    keenkiller
    keenkiller
    Aug 18, 2021
    71
    不需要框架,直接用 net 包就行

    一般用 bufio.Scanner 的 Split 就可以拆分 token 了

    如果想简单点可以直接用 websocket
    deavorwei
    deavorwei
    Aug 18, 2021
    72
    @ming159 您好,请教下粘包的问题。TCP 有重传机制和 ACK 机制,经过 TCP 传输的数据包应该是可靠的。应用层拿到的数据包应该也是完整的、有序的,为何会出现应用层接收到数据包是不完整或者是乱序的情况。---来自没有开发经验的小学生
    nowgoo
    nowgoo
    Aug 18, 2021❤️6
    73
    是个程序员都明白,人家问的就是应用层有没有“从字节流中拆出消息”的轮子。粘包警察纠着“粘包”两个字不放有意思吗?难道楼主不知道 TCP 是流协议,要你教?

    楼主明明说了使用“粘包”和“拆包”是因为描述方便。粘包警察会因为老婆饼里没老婆跟老板打一架吗?
    darknoll
    darknoll
    Aug 18, 2021
    74
    @ming159 那你得把问题表达出来啊,什么情况下不能用这种模式,问题都不说来别人怎么 show code 啊。
    blessingsi
    blessingsi
    Aug 18, 2021 via Android
    75
    @deavorwei 理解一下[流]协议这个说法。TCP 协议的有序性和完整性保证是针对整个流来说的,并不是代表接受端的每次 read 拿到的恰好是发送端每次 write 的内容。比如,当 TCP 一个包过大的时候,会在实际传输的时候拆开
    Lemeng
    Lemeng
    Aug 18, 2021
    76
    学习学习来的,绑定一下
    mxT52CRuqR6o5
    mxT52CRuqR6o5
    Aug 18, 2021 via Android
    77
    我觉得你需要的并不是裸 TCP
    Guidance3204
    Guidance3204
    Aug 18, 2021
    78
    我前几天正好写了一个序列化,反序列化消息到 struct 的库 https://github.com/lai323/bytecodec
    zxCoder
    zxCoder
    Aug 18, 2021
    79
    @nowgoo 真的是笑死了,粘包警察和 c++的语言律师简直就是编程界两大 sb
    Frytea
    Frytea
    Aug 18, 2021
    80
    ZeroMQ? 之前做 C 开发经常用
    maplelin
    maplelin
    Aug 18, 2021
    81
    @deavorwei #72 很简单的举例,水管漏了,中间有一部分数据丢掉了。但是不代表后面的数据就不能正确到达目的地。有序只是接受端和发送端会按照顺序发送数据和接受数据,并不代表每次都会等到收到接受端前一个数据已收到的状态码才发送下一段数据,这样效率是很低下的。
    Michaelssss
    Michaelssss
    Aug 18, 2021
    82
    你要写裸 TCP ?首先就是先定义 Frame 或者 Protocol,然后基于上述将 Payload 用于业务=。=详情见 HTTP 是怎么做的。。。一个意思
    ming159
    ming159
    Aug 18, 2021
    83
    @darknoll 54 楼 并不是虚构的协议. 可以参考
    1. Modbus ASCII 在 ASCII 传输模式下,消息帧以英文冒号”:”( 3A )开始,以回车( 0D )和换行( 0A )结束.
    2. 基恩士 PLC 中的 上位链路协议: [功能码] 开始,回车( 0D )结束.
    dbpe
    dbpe
    Aug 18, 2021
    84
    哈哈哈....笑死

    谁知道 http1.1 的长链接是怎么做的呢...


    斜眼笑
    ming159
    ming159
    Aug 18, 2021
    85
    @deavorwei
    TCP 保证了 有序性,完整性. 是指:
    发送端 发送了 #1 2 3 4 5$ #a b c d e$ . 接收端最终收到的也是 #1 2 3 4 5$ #a b c d e$ 有序,且完整.
    但是

    接收过程

    接收过程

    接收过程

    (重要的点) 会是这样的
    情况 1: #1 2 3 4 5$ #a b c d e$
    情况 2: #1 2 3 和 4 5$ #a b c d e$
    顺序没乱,且数据没丢.
    jsq2627
    jsq2627
    PRO
    Aug 18, 2021
    86
    23333 当看到 LZ 写了“粘包”两字就猜到帖子的走向了。
    wengang285
    wengang285
    Aug 18, 2021❤️1
    87
    @ming159 长度( 4 字节)+buffer,缓冲区可读,那么查看先读长度,然后根据长度往后取 buffer,长度不够这次就不取,等待底层( epoll )的再次通知
    ace12
    ace12
    Aug 18, 2021 via Android
    88
    看到粘包,我就兴奋了哈哈哈
    SillyChenBrother
    SillyChenBrother
    Aug 18, 2021❤️3
    89
    TCP 没有所谓的粘包说法

    网络层,IP 数据报帮你分报,在这里会切块
    传输层,TCP 帮你分块,这里也会分块,但 UDP 就不会分

    TCP 传过来,你通过程序收到的数据肯定是不会破损的,都三次握手四次放手,拥塞控制,失败重传,流水线运输,传过来就都是对的数据。

    数据是一个流,过来的一个个报文,也就是所谓的包,你要自己处理数据边界,也就是说你自己定义的应用层协议必须处理如何区分边界的问题,比如发现开头是 Xx 就是你的一个切确的文本的开始,或者叫结构体的开始,直到 yyy 就是文本的结束,以此反复,也就是解码和编码的问题,也就是说这已经不是传输层的问题了,这是应用层了,参考 http,ftp 等协议,gRPC/thrift 这种序列化解编码就是你文中描述所需要用到,所以粘包的描述是多年来的玄之又玄的说法,每次听起来一头雾水,然后面试官还喜欢装逼问这个。

    设计好解编码二进制的序列化应用层协议,就没有所谓的粘包,拆包,朦朦胧胧,龙龙萌萌
    ming159
    ming159
    Aug 18, 2021
    90
    @wengang285
    但也可以是 长度( 4 字节)+buffer,缓冲区可读,那么查看先读长度,然后根据长度往后取 buffer,有多少取多少,因为没有取够, 那么下一次再次通知的时候,与上一次的已经取出来的拼接,直到取够 "长度" 为一次完整帧.
    tonyan93
    tonyan93
    Aug 18, 2021
    91
    粘包并不是 TCP 协议造成的,它的出现是因为应用层协议设计者对 TCP 协议的错误理解,忽略了 TCP 协议的定义并且缺乏设计应用层协议的经验。
    JoeBreeze
    JoeBreeze
    Aug 18, 2021
    92
    TCP: 你们在说啥?
    lesismal
    lesismal
    Aug 18, 2021
    93
    足够满足楼主和各位各种业务场景:
    https://github.com/lesismal/arpc
    lesismal
    lesismal
    Aug 18, 2021
    94
    @abersheeran 没办法,"粘包" 虽然是错误的概念,但已约定俗成,懂的人只是用这个词沟通问题
    D3EP
    D3EP
    Aug 18, 2021
    95
    Golang 这种阻塞 IO 模型还要什么框架..
    wengang285
    wengang285
    Aug 18, 2021
    96
    @ming159 也可以,但是这样会导致解码的逻辑多处理一个分支,增加代码的复杂性,但是并没有带来性能的提升,实际工程中不会这么写
    ming159
    ming159
    Aug 18, 2021
    97
    @wengang285 根据实际场景选择吧,例如 数据量相对较大,且 buffer 小的时候,如果不尽快从 buffer 中取出数据, 引发 流量控制机制,反而导致整体传输变慢.
    LewisW
    LewisW
    Aug 18, 2021
    98
    @noe132 你也太神了 顶级预测
    xuanbg
    xuanbg
    Aug 18, 2021
    99
    老老实实用一个 http 之类的应用层协议,而不是把 TCP 协议当应用层协议用,哪来的粘包。
    lesismal
    lesismal
    Aug 18, 2021
    100
    介绍下自己俩库,arpc 和 nbio:
    https://www.v2ex.com/t/794435#reply0

    这两个库可以覆盖绝大多数应用业务场景,比如:RPC 、IM 、游戏、广播 /推送服务、其他自家功能交互等。
    支持 tcp/kcp/quic/websocket 各种协议作为传输载体。
    单机连接数量不特别大比如 10k-100k 这种级别的(普通人眼里觉得 10k 已经算大了,但是对于网络框架而言,这个量级很小,那些性能差的脚本语言就不要来讨论性能了),配置能扛得住就默认标准库方案。
    海量并发比如单机 100k-1000k 这种级别的,可以 arpc+nbio,照样能扛。
    这个领域里,一是性能,二是易用性,有兴趣的同学可以自行对比。
    关于性能,有兴趣的同学可以去看下鸟窝老师和字节同学的 benchmark 库,硬件不同压测结果可能存在差异,所以有兴趣的同学不要看仓库文档展示的结果,请自己机器实测看效果:
    github.com/rpcxio/rpcx-benchmark
    github.com\cloudwego\kitex-benchmark
    1  2  
    ❮ ❯
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3170 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 147ms · UTC 10:40 · PVG 18:40 · LAX 02:40 · JFK 05:40
    ♥ Do have faith in what you're doing.