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

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

  •  
  •   wlgqa · Mar 23, 2022 · 4806 views
    This topic created in 1686 days ago, the information mentioned may be changed or developed.

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

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

    https://github.com/vishvananda/netlink

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

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

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

    你能再更详细的描述一下你的需求吗?
    liaotonglang
    liaotonglang
    Mar 24, 2022
    27
    ss -tm 就可以看
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1773 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 79ms · UTC 23:58 · PVG 07:58 · LAX 15:58 · JFK 18:58
    ♥ Do have faith in what you're doing.