Go 怎么实现 http 请求读到一定的字节数之后立刻返回? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
EthanDon
V2EX    程序员

Go 怎么实现 http 请求读到一定的字节数之后立刻返回?

  •  
  •   EthanDon 209-06-21 20:07:51 +08:00 3485 次点击
    这是一个创建于 2306 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我在网上冲浪两天了也没发现方法

    第 1 条附言    2019-06-24 11:28:13 +08:00
    已经结贴了,读取 respinse 的时候是流式读取,自己定义结构就 OK 了,感谢各位大佬
    34 条回复    2019-06-24 12:22:35 +08:00
    Vegetable
        1
    Vegetable  
       2019-06-21 20:12:25 +08:00
    http 是半双工的,这个和需求好像是矛盾的,读到一半断开应该是可以,返回的话还算是 http 吗?
    misaka19000
        2
    misaka19000  
       2019-06-21 20:17:55 +08:00 via Android
    自己解析豹纹呗
    ruoxie
        3
    ruoxie  
       2019-06-21 20:18:06 +08:00
    查一下 Range 请求头相关的
    blackcurrant
        4
    blackcurrant  
       2019-06-21 20:21:58 +08:00
    "网上冲浪" 好久没听到这个词了
    EthanDon
        5
    EthanDon  
    OP
       2019-06-21 20:23:53 +08:00
    @Vegetable 也是,返回之后并不知道是不是请求成功了,状态码是不是 200
    EthanDon
        6
    EthanDon  
    OP
       2019-06-21 20:24:38 +08:00
    @misaka19000 需求是还在传输阶段就段卡,解析报文应该得等到所有报文都到达了才能进行吧?
    EthanDon
        7
    EthanDon  
    OP
       2019-06-21 20:26:35 +08:00
    @ruoxie range 已经用上了,现在的需求时指定了 range 之后,发送请求,为了防止响应的报文过大长时间阻塞在这个 http 请求上,需要在读取一定的数据后就返回
    不知道 go 里可不可以在超时以后返回已经读到的数据
    guonaihong
        8
    guonaihong  
       2019-06-21 20:30:09 +08:00
    这个需求有点类似开发 API 网关,要限制流量的 limit 指令。
    你只要自己实现 Read 接口赋值给 r.Body。自己实现的接口加个计算器就行。
    misaka19000
        9
    misaka19000  
       2019-06-21 20:30:40 +08:00
    你这个需求可以用 nginx 实现,client_max_body_size
    blless
        10
    blless  
       2019-06-21 20:34:17 +08:00 via Android
    bufio 还是哪个库 可以创建一个指定大小的 reader,读到后检查一下是不是 EOF 应该可以吧
    loading
        11
    loading  
       2019-06-21 20:36:02 +08:00
    @blackcurrant “网上冲浪了两天”用时髦点的说法有两种:
    1.在网上浪了两天。
    2.滑水了两天。
    cabing
        12
    cabing  
       2019-06-21 20:39:19 +08:00
    为啥要读取一段字段就立即返回呢?
    loading
        13
    loading  
       2019-06-21 20:39:25 +08:00
    楼主的需求是怕阻塞太久,虽然计算发送字节后主动切断是可以,但是我认为你应该用计时器做,毕竟你关心的似乎是时长?
    EthanDon
        14
    EthanDon  
    OP
       2019-06-21 20:43:26 +08:00
    @cabing
    @loading 时长是一方面,另一方面关心网络情况,需要验证服务器能否在超时时间内返回足够多的数据
    EthanDon
        15
    EthanDon  
    OP
       2019-06-21 20:44:56 +08:00
    @guonaihong r 是 request 吗?兄台可否细说?多谢!
    EthanDon
        16
    EthanDon  
    OP
       2019-06-21 20:45:26 +08:00
    @misaka19000 项目是轻依赖哦,整个环境除了 go 没其他的了
    guonaihong
        17
    guonaihong  
       2019-06-21 20:47:01 +08:00
    @blless 用 bufio,又开辟了一个 buf,多了一层内存拷贝。如果只是关心个数,只用一个计数器就行。 比如定义如下结构
    ```go
    type maxBytesReader struct {
    w http.ResponseWriter
    r io.ReadCloser // underlying reader
    n int64 // max bytes remaining
    err error // sticky error
    }
    ```
    polebug
        18
    polebug  
       2019-06-21 20:47:44 +08:00
    你这得实时解析报文啊 还得计数 真的不会影响性能吗
    guonaihong
        19
    guonaihong  
       2019-06-21 20:48:28 +08:00
    @EthanDon r 是 http.Request。
    guonaihong
        20
    guonaihong  
       2019-06-21 20:51:13 +08:00
    @EthanDon 兄台有感觉了麻?
    loading
        21
    loading  
       2019-06-21 20:55:39 +08:00
    我给你浪了 10 分钟:
    aHR0cHM6Ly9jb2xvYnUuY29tLzIwMTYvMDcvMDEvdGhlLWNvbXBsZXRlLWd1aWRlLXRvLWdvbGFuZy1uZXQtaHR0cC10aW1lb3V0cy8=

    如何切断一个 http,都是在基础包的代码里面。

    如果你说的是 request,你应该知道如何浪出来吧。
    gamexg
        22
    gamexg  
       2019-06-21 20:56:48 +08:00
    ?
    http 标准库的 body 本身是流式实现,你需要多长的 body 就读取多长,读够后直接关闭即可。

    另外 http.Client 带超时控制,可能是你想要的。

    如果需要更底层的控制,可以自己建立 tcp 连接,然后 http.NewRequest 后直接 Write 到自己的 tcp 连接。读取时使用 http.ReadResponse 读取即可。http.ReadResponse 接收的是 bufio.Reader,意味着你可以用 io.LimitReader 封装 tcp 连接实现限制尺寸。
    gamexg
        23
    gamexg  
       2019-06-21 20:57:43 +08:00
    @gamexg #22 htt.Get 等函数只要接收到 http 响应头即可返回 ,body 等内容是你从 Body 读取时才从 tcp 连接读取的。
    Leigg
        24
    Leigg  
       2019-06-21 21:05:32 +08:00 via iPhone
    数据分段传啊
    guonaihong
        25
    guonaihong  
       2019-06-21 21:10:19 +08:00
    @EthanDon 这是 gin 里面 limit 模块代码, 可以参考下。https://github.com/gin-contrib/size

    本来准备写一个的,发现有现成的。
    Vegetable
        26
    Vegetable  
       2019-06-21 21:38:11 +08:00
    @EthanDon 傻了都,这不就是 nginx 的 413 吗?参照这个逻辑设计肯定行得通的.
    flynaj
        27
    flynaj  
       2019-06-22 09:22:05 +08:00 via Android
    HTTP 协议不成的话,你可以 socket 编程。自己处理数据包,只是工程有点大。
    EthanDon
        28
    EthanDon  
    OP
       2019-06-24 11:16:46 +08:00
    @guonaihong 周末去浪浪,我这就去了解一下
    EthanDon
        29
    EthanDon  
    OP
       2019-06-24 11:18:30 +08:00
    @Vegetable 主要是不能用 nginx。。。自己造轮子的话对 go 还不太熟悉。。。
    EthanDon
        30
    EthanDon  
    OP
       2019-06-24 11:25:20 +08:00
    @gamexg 啊明白了,我以为哪个 response 是读完才返回的,可以结贴了!感谢大佬
    EthanDon
        31
    EthanDon  
    OP
       2019-06-24 11:26:06 +08:00
    @guonaihong 我去康康
    @flynaj 感谢各位,结贴了
    EthanDon
        32
    EthanDon  
    OP
       2019-06-24 11:26:39 +08:00   1
    @loading 找到了解决方法,感谢
    EthanDon
        33
    EthanDon  
    OP
       2019-06-24 11:27:12 +08:00
    @loading 大佬浪的姿势比我好啊,请问一哈关键字和引擎是啥,我搜的都不知道是啥玩意
    loading
        34
    loading  
       2019-06-24 12:22:35 +08:00 via Android
    @EthanDon golang 的网络基础库,虽然我还没开始看,到时我知道请求能断,所以我搜索了几个关键字。
    golang net 断 关 这些,用 google。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3503 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 10:39 PVG 18:39 LAX 03:39 JFK 06:39
    Do have faith in what you're doing.
    ubao 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