求助各位大神一个问题! 感谢

pjc685 · 2014-11-07 10:25:37 · 2416 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2014-11-07 10:25:37 的主题,其中的信息可能已经有所发展或是发生改变。

response, err := client.Do(reqest)
defer response.Body.Close()

当我client.Do(reqest) 完了以后,所有数据是已经在内存里面了吗?

ioutil.ReadAll(response.Body) 还是这个才是从服务网GET数据下来?

如果我想控制下载的速度,是不是就是在read这一步 限制下读取速度?(前提是read的时候,是从服务器上拉数据...,代码在下面..)

buf := make([]byte, 1024)

for {
    n, err := r.Body.Read(buf) 

    if err != nil {
        break
    }
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2416 次点击  
加入收藏 微博
6 回复  |  直到 2014-11-11 10:06:07
xuanbao
xuanbao · #1 · 10年之前

嗯,是这样的。网络 IO,读的时候才会获取数据。

相关跟代码:transfer.go?s=7038:7050#L290

polaris
polaris · #2 · 10年之前

HTTP 请求一旦发出,服务端不管你读不读,都会响应数据,也就是数据会传输过来,不过,这时候数据是在操作系统实现的协议栈的buffer中,也就是操作系统保存了。

从 resp.Body 中读,只是从协议数据中把数据读到当前程序中。不会影响网路数据的传输。

polaris
polaris · #3 · 10年之前

补充一下,你可以通过 Wireshark 之类的抓包工具来试试着两种情况。

rockxsj
rockxsj · #4 · 10年之前
polarispolaris #2 回复

HTTP 请求一旦发出,服务端不管你读不读,都会响应数据,也就是数据会传输过来,不过,这时候数据是在操作系统实现的协议栈的buffer中,也就是操作系统保存了。 从 resp.Body 中读,只是从协议数据中把数据读到当前程序中。不会影响网路数据的传输。

那么buffer满了是不是就不读了?等待取走才会接着从io读取?

polaris
polaris · #5 · 10年之前
rockxsjrockxsj #4 回复

#2楼 @polaris 那么buffer满了是不是就不读了?等待取走才会接着从io读取?

如果 buffer 满了,客户端会通过 winsize=0 告知服务端 buffer 满了,这时服务端不会再发送数据,而是会检测客户端啥时候buffer酉空间了(或客户端酉空间了告知服务端)。因此,从这个意义上来说,可以通过控制读取速度来控制从服务器拉数据的速度。

Linux TCP socket buffer 相关的知识:

socket buffer size缺省为64 kB.

理论上,最优的buffer大小为*

可以通过下列命令改变其大小(如256KB)

% sysctl -w net.core.rmem_max=262144 ;最大的接收缓冲区大小(tcp连接)

% sysctl -w net.core.wmem_max=262144 ;最大的发送缓冲区大小(tcp连接)

% sysctl -w net.core.rmem_default=262144;缺省的接收缓冲区大小(tcp连接)

% sysctl -w net.core.wmem_default=262144;缺省的发送缓冲区大小(tcp连接)


这些参数在proc/sys下面可以看到;

sysctl -p | grep mem:显示当前缓冲区设置

round-trip delay 可由ping命令得到。
polaris
polaris · #6 · 10年之前

推荐看看 火丁笔记的 《关于FIN_WAIT1》 这篇文章

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传