Golang Go语言中有什么TCP框架?

发布于 1周前 作者 caililin 来自 Go语言

Golang Go语言中有什么TCP框架?
可以管理连接, 心跳包 处理粘包等,
web 方面的很多, tcp 的没找到,大家做 TCP 都用什么呢?

101 回复

rpcx

更多关于Golang Go语言中有什么TCP框架?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


#2 不是 我要做的是 c/s , 用 net 包可以,但是连接管理, 心跳包 粘包等要自己处理,想问下 TCP/IP 有没有什么框架.大家都用什么…好像用 go 做这个的少吧.

粘包警察还有 5 分钟到达战场

#4 小白听不懂啊.

#5 这个是 http 库吧.

#1 谢谢,现在好像都是用 rpc 了? 到现在也也不是太懂 rpc,以为比传统的 tcp 通讯复杂,也没仔细看过.
刚查的,是这样吗? https://www.zhihu.com/question/41189095

grpc 简单高效

粘包警察虽迟但到

grpc,既现代又高效,跨平台、工具集完备

#12 粘包警察虽迟但到 啥意思啊, 虽迟但到懂. 粘包警察不懂啥意思.

就是有人喜欢说 tcp 黏包之类的话

就用 net 库,做过一个项目,粘包没出现过

TCP 哪来的粘包,建议重修网络原理

只有 TCP 有粘包啊

CS 架构其实也可以用 HTTP 的,如果需要双向通信可以 Websocket 。如果种种考虑不想选择 HTTP 的话,首选建议是 grpc,类似的替代方案也有 messagepack 或是 Go 自己的 gob 也

TCP 哪来的粘包,建议重修网络原理 +1

粘包警察虽迟但到

TCP 哪来的粘包,建议重修网络原理 +1

粘包警察又抓获一名自投罗网的

流 流 流,说三遍

golang 用 net 库处理不是很麻烦吧。

除非 rpc 不满足需求否则就用 rpc 就好






你们是没用过 TCP 吧,就是因为流,才需要处理粘包、分包问题,不懂不要乱喷,好好补补知识

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,然后框架会帮你处理所谓的“粘包半包”问题。

gotty
gnet

类似 netty 的框架.

不懂 TCP 才会说粘包

一群人不知道抓住个概念争论个什么,真的把 TCP 学明白了,用什么词汇都可以把这东西给人描述明白。粘拆又何妨,反正应用层能拿到完成的业务 package 。

这么多年,就一直没搞懂这些说粘包的。难道你们协议头里没有 magic code, 没有数据包 length?

evio, gnet, netpoll

https://pkg.go.dev/net 这个包? 类似 其他语言 socket api

粘包警察的工作不到位啊,都批了这么久了,还有人以为存在“粘包”这种伪概念……

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

你们会碰到“粘包”是因为你们在 TCP 之上定义的协议有问题,说明定义这个协议的人没学好

正是因为流协议所以才没有“粘包”的说法,TCP 就像一条水管,数据是源源不断流过去的,特性就是这样。TCP 会导致“粘包”这个说法是不对的,TCP 和粘包不存在因果关系

#39 有点扣字眼了,当然不是说流粘,说的是你发的消息变成流传输,你的多个消息粘在一起了。

“粘包”还行

建议 #17 #18 打一架

短短几句话就暴露了小白一个,很幼稚

这……算了,你继续粘包吧,培训班害死人

看了评论我想学习学习(我只会 curd)

可是 你们谁也不说个原理

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

那你们倒是说说啊…

用 RPC 或者 websocket 吧,除了游戏已经很少看到跑裸 TCP 的了

TCP 本就是流协议,没有包的概念。如果需要划分包,一定是要在上层协议里设计长度标识位来划分包和包之间的隔离线。例如 HTTP 里的 Content-Length,Socks 里的 domain-length 等等。

举个现实里的例子:TCP 协议就是一根水管,你拿着许多瓶矿泉水往管子对面输水,对你来说,水是一瓶瓶的,之间的区别很明显。但对于那边的人来说他只能收到一波又一波的水,至于这些水是属于哪一瓶的,他不知道。如果运气好,每一波水之间间隔也会很明显,但是这并不代表水管帮你把这些水分割了。运气不好的时候,水就连在一起下来了,这就是他们嘴里说的粘包。

TCP 本身协议不存在粘包说法, 数据传输中的粘包是自定协议没有定义好

假设有一个数据源,源源不断的产生数据,需要通过 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){
// 请把这里补充完整,就理解了.
}







"Talk is cheap ,Show me the code"
请贴出你们针对 54 楼问题的代码

TCP 就是 水管出水, 你用 定量 100ml 的杯子接水, 这次接 50ml, 但是每次都接满, 你要喝的时候就喝一半, 喝多少定着杯子的刻度尺就行

#55 谢谢,早就发现这个 gnet 了,这个库没有发现 demo,不知道为啥.

粘包是什么鬼,拿胶水粘的吗

应用层出问题,非要怪到网络层( TCP )?

TCP 协议里明明白白写了:面向流。它把数据以流的形式,可靠地发送给接收方,它的事情就完美地做完了。
你们提出的“粘包”概念是应用层自己该解决的,你们可以说,应用层的粘包问题,但说“TCP 的粘包问题”,是不严谨的

你不能直接发数据啊,你得在前面加上协议 magic number+数据长度

你说的这是一种,我没记错,应该叫做 “定长协议” ,就是一个数据段固定长度,比如 512 个字节.每次固定取这么长度的就可以.
但是还有"可变长度"的协议,就需要在数据段中某个固定位置上指示 本次数据自身的长度,例如: #3abc,#5abcde.
表示 #开头,随后的数字表示后续数据的长度,比如 3,5,分别表示在此之后还有若干个数据才算一段完整的数据集.

还有另外一种,固定以回车换行符为分隔符的,无论多长,只要有回车换行符就切断

这本来就是应用层的问题,你们非要往网络层扯?

我家鸡蛋孵出来了一只鸡,但是这只鸡不会飞是什么原因?
粘包警察:鸡蛋都没有翅膀,怎么可能会飞!

“TCP 的粘包问题” 确实不严谨.这点我也承认.

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

如果写过 TCP 通信(Socket 编程)的懂得自然懂,不懂得说多了也没用, 可以参考 Netty 中的
LineBasedFrameDecoder : 基于回车换行符的解码器
DelimiterBasedFrameDecoder: 分隔符解码器,可以指定消息结束的分隔符
FixedLengthFrameDecoder: 固定长度解码器,它能够按照指定的长度对消息进行自动解码
LengthFieldBasedFrameDecoder :一般协议头中带有长度字段,通过使用 LengthFieldBasedFrameDecoder 传入特定的参数,来解决拆包粘包

#62 严格来说是这样的,但是人与人沟通没必要这么抠字眼,能理解就行,就像叫人吃饭,难道就真的只吃饭不吃菜?

楼主只是想找个在应用层可以处理粘包问题的框架,并没有将“粘包问题”甩锅给 TCP 的意思,但是为什么要抓住这个点不放呢?

自己包下 net 库吧

不是说所有协议都是这种模式"magic number+数据长度". 自己研究去吧

因为抓不到其他的点.

不需要框架,直接用 net 包就行

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

如果想简单点可以直接用 websocket

您好,请教下粘包的问题。TCP 有重传机制和 ACK 机制,经过 TCP 传输的数据包应该是可靠的。应用层拿到的数据包应该也是完整的、有序的,为何会出现应用层接收到数据包是不完整或者是乱序的情况。—来自没有开发经验的小学生

是个程序员都明白,人家问的就是应用层有没有“从字节流中拆出消息”的轮子。粘包警察纠着“粘包”两个字不放有意思吗?难道楼主不知道 TCP 是流协议,要你教?

楼主明明说了使用“粘包”和“拆包”是因为描述方便。粘包警察会因为老婆饼里没老婆跟老板打一架吗?

那你得把问题表达出来啊,什么情况下不能用这种模式,问题都不说来别人怎么 show code 啊。

理解一下[流]协议这个说法。TCP 协议的有序性和完整性保证是针对整个流来说的,并不是代表接受端的每次 read 拿到的恰好是发送端每次 write 的内容。比如,当 TCP 一个包过大的时候,会在实际传输的时候拆开

学习学习来的,绑定一下

我觉得你需要的并不是裸 TCP

我前几天正好写了一个序列化,反序列化消息到 struct 的库 https://github.com/lai323/bytecodec

真的是笑死了,粘包警察和 c++的语言律师简直就是编程界两大 sb

ZeroMQ? 之前做 C 开发经常用

#72 很简单的举例,水管漏了,中间有一部分数据丢掉了。但是不代表后面的数据就不能正确到达目的地。有序只是接受端和发送端会按照顺序发送数据和接受数据,并不代表每次都会等到收到接受端前一个数据已收到的状态码才发送下一段数据,这样效率是很低下的。

你要写裸 TCP ?首先就是先定义 Frame 或者 Protocol,然后基于上述将 Payload 用于业务=。=详情见 HTTP 是怎么做的。。。一个意思

54 楼 并不是虚构的协议. 可以参考
1. Modbus ASCII 在 ASCII 传输模式下,消息帧以英文冒号”:”( 3A )开始,以回车( 0D )和换行( 0A )结束.
2. 基恩士 PLC 中的 上位链路协议: [功能码] 开始,回车( 0D )结束.

哈哈哈…笑死

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


斜眼笑


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$
顺序没乱,且数据没丢.

23333 当看到 LZ 写了“粘包”两字就猜到帖子的走向了。

长度( 4 字节)+buffer,缓冲区可读,那么查看先读长度,然后根据长度往后取 buffer,长度不够这次就不取,等待底层( epoll )的再次通知

看到粘包,我就兴奋了哈哈哈

TCP 没有所谓的粘包说法

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

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

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

设计好解编码二进制的序列化应用层协议,就没有所谓的粘包,拆包,朦朦胧胧,龙龙萌萌


但也可以是 长度( 4 字节)+buffer,缓冲区可读,那么查看先读长度,然后根据长度往后取 buffer,有多少取多少,因为没有取够, 那么下一次再次通知的时候,与上一次的已经取出来的拼接,直到取够 “长度” 为一次完整帧.

粘包并不是 TCP 协议造成的,它的出现是因为应用层协议设计者对 TCP 协议的错误理解,忽略了 TCP 协议的定义并且缺乏设计应用层协议的经验。

TCP: 你们在说啥?

足够满足楼主和各位各种业务场景:
https://github.com/lesismal/arpc

没办法,“粘包” 虽然是错误的概念,但已约定俗成,懂的人只是用这个词沟通问题

Golang 这种阻塞 IO 模型还要什么框架…

也可以,但是这样会导致解码的逻辑多处理一个分支,增加代码的复杂性,但是并没有带来性能的提升,实际工程中不会这么写

根据实际场景选择吧,例如 数据量相对较大,且 buffer 小的时候,如果不尽快从 buffer 中取出数据, 引发 流量控制机制,反而导致整体传输变慢.

你也太神了 顶级预测

老老实实用一个 http 之类的应用层协议,而不是把 TCP 协议当应用层协议用,哪来的粘包。

介绍下自己俩库,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

在Golang(Go语言)中,有多个TCP框架可供选择,这些框架各具特色,适用于不同的应用场景。以下是一些知名的TCP框架:

  1. goev

    • 特性:轻量、极简方式实现Reactor模型,支持异步响应,完美解决per-connection per-goroutine的问题,对GC友好。
    • 适用场景:RPC服务、游戏服务、proxy、nosql、mq等基于TCP协议的高性能网络服务。
  2. TCPX

    • 特性:纯Golang开发,具备TCP通信中常见问题的解决方案,如拆包、心跳检测等。仿制HTTP框架gin,支持中间件模式,使用简便。
    • 仓库地址:https://github.com/fwhezfwhez/tcpx
  3. Kinx(或Zinx的变种):

    • 特性:通过线程池+任务队列来管理goroutine,提高资源利用率。支持自定义协议解决TCP粘包问题,具备心跳检测功能。
    • 仓库地址:https://github.com/k-si/Kinx

此外,Go语言的标准库net也提供了丰富的TCP网络通信接口,开发者可以基于标准库创建和管理TCP网络服务。对于简单的TCP服务器和客户端实现,标准库已经足够强大和灵活。在选择TCP框架时,建议根据项目的具体需求和性能要求来选择最合适的框架。

回到顶部