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 · 3557 次点击
    这是一个创建于 961 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如 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
    你要在乎这个就别用 go ,不讲究才符合 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   ·   实用小工具   ·   2767 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 01:59 · PVG 09:59 · LAX 17:59 · JFK 20:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.