golang 有没有办法获取当前 TCP 发送缓存区剩余空间。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
wlgqa
V2EX    Go 编程语言

golang 有没有办法获取当前 TCP 发送缓存区剩余空间。

  •  
  •   wlgqa 2022-03-23 17:25:15 +08:00 3998 次点击
    这是一个创建于 1306 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如 TCP 发送缓冲区 10k,已经写了 8K ,剩余 2K 。有办法获取吗。

    27 条回复    2022-03-24 18:48:53 +08:00
    MidGap
        1
    MidGap  
       2022-03-23 17:34:11 +08:00
    net.Conn.Write()会返回写了多少
    wlgqa
        2
    wlgqa  
    OP
       2022-03-23 17:36:54 +08:00
    @MidGap 这样只知道缓存是否写满。
    proxytoworld
        3
    proxytoworld  
       2022-03-23 17:54:27 +08:00
    这是内核层了吧
    guaji123
        4
    guaji123  
       2022-03-23 17:54:44 +08:00
    好久没写过底层代码了,请教下 C 语言能做到吗 ?
    ysc3839
        5
    ysc3839  
       2022-03-23 18:01:04 +08:00
    SO_SNDBUF?
    est
        6
    est  
       2022-03-23 18:05:04 +08:00
    可以通过反射 getsockopt 读 SOCK_INFO 获取缓冲区有多大,写了多少这个。。。。真不知道。
    Buges
        7
    Buges  
       2022-03-23 18:11:58 +08:00 via Android
    你要在乎这个就别用 g ,不讲究才符合 go 的理念。
    wlgqa
        8
    wlgqa  
    OP
       2022-03-23 18:20:28 +08:00   1
    @Buges 请这位大神牛,给我们讲讲自己写过啥著名 go 项目
    CEBBCAT
        9
    CEBBCAT  
       2022-03-23 18:30:16 +08:00 via iPhone
    获取缓存区剩余大小是做什么用的呢?
    Buges
        10
    Buges  
       2022-03-23 18:32:53 +08:00 via Android   15
    @wlgqa 阴阳怪气个啥,go 就是这样子的啊,为了保持“简单性”,把 go 团队认为不重要的“细节”能隐藏则隐藏能默认则默认。你要是想精确地控制细节或确保代码的准确性,建议你换 rust 。
    可以参考一下 go 是如何“解决”时间单调性问题的:
    https://github.com/golang/go/issues/12914
    jim9606
        11
    jim9606  
       2022-03-23 18:37:11 +08:00
    如果 C 可以,那 golang 应该可以通过获取 fd 之后用 C 相同的方法查询。这个肯定是特定 OS 耦合的方法。
    C 使用 getsockopt TCP_INFO 能获得一些状态信息。
    不过我觉得你都用 go 了,不应该用这种方式应对写阻塞。
    airqj
        12
    airqj  
       2022-03-23 18:51:13 +08:00
    这个应该跟语言无关了
    bruce0
        13
    bruce0  
       2022-03-23 18:54:37 +08:00
    如果 C 能做的话, go 应该可以通过 syscall 实现, 前提是 go 有对应的系统调用
    ManjusakaL
        14
    ManjusakaL  
       2022-03-23 19:13:37 +08:00 via iPhone
    和 Go 无关啊。。。走 NETLINK 的 TCP-DIAG 能拿

    https://github.com/vishvananda/netlink

    倒是有个还不错的封装
    xdeng
        15
    xdeng  
       2022-03-23 19:31:05 +08:00
    用 go 为啥会有这个需求,go 的 tcp_nodelay 默认为真的。
    wlgqa
        16
    wlgqa  
    OP
       2022-03-23 20:27:05 +08:00
    @Buges 大神啊,请教 Rust 怎么实现这个需求。大神还给标准库 time 提交过代码?
    vance123
        17
    vance123  
       2022-03-23 20:51:56 +08:00
    首先要看内核层是否提供了这个接口,没提供的话应用层是毫无办法的
    fireleaves
        18
    fireleaves  
       2022-03-23 21:27:56 +08:00   19
    我没有理解为什么 op 会对 @Buges 穷追不舍。
    Buges 措辞上可能有点歧义,但是表达的意思应该没有恶意吧。在补充的回复甚至给出了一个佐证,我自问是做不到他这样被“怼”了之后还能如此回复的。
    masterclock
        19
    masterclock  
       2022-03-23 21:42:02 +08:00
    同不理解,@Buges 措辞上似乎也没啥歧义,go 就是这思路啊,用合适的工具做合适的事情挺好
    zhs227
        20
    zhs227  
       2022-03-23 22:49:11 +08:00
    golang 自己写代码通过 syscall 调用 getsockopt 来实现。初步估计 golang 自身的 tcp 库可能没有这个功能。TCPConn 一共就一二十个方法。
    iyaozhen
        21
    iyaozhen  
       2022-03-23 23:57:46 +08:00
    这个没弄过,虽然写过几个 socket 程序

    不过为啥有这个需求,实际上缓冲区(特别是发送),变化非常快,对端如果没阻塞的话
    wangritian
        22
    wangritian  
       2022-03-24 00:05:27 +08:00
    不要再怼认真回答你问题的人了
    另外建议你讲一下原始需求
    mxT52CRuqR6o5
        23
    mxT52CRuqR6o5  
       2022-03-24 00:32:16 +08:00 via Android
    做不到难道不是一种回答?(不论这个回答正确与否)
    qrobot
        24
    qrobot  
       2022-03-24 08:49:22 +08:00
    golang 当然是可以的啊, 手动实现一个 TCP/IP 栈就可以了
    coolrc
        25
    coolrc  
       2022-03-24 09:52:01 +08:00 via iPhone
    什么阴阳人
    kxuanobj
        26
    kxuanobj  
       2022-03-24 10:07:05 +08:00   1
    TCP 缓冲区大小在内核是随时变化的。即便有接口让你拿到当前缓冲区大小,在系统调用返回之前,这个值也可能发生变化。
    这个没啥用啊。

    如果你担心数据延迟,就不应该使用 TCP 协议。
    如果你担心 Write 阻塞,你可以用非阻塞操作,或者异步 io 类操作。

    你能再更详细的描述一下你的需求吗?
    liaotonglang
        27
    liaotonglang  
       2022-03-24 18:48:53 +08:00
    ss -tm 就可以看
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     841 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 22:31 PVG 06:31 LAX 15:31 JFK 18:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86