GO中 TCP 的receivebuffSize sendBufSize 第一次偶尔失效

wangbintao1992 · 2017-12-21 02:54:12 · 1151 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-12-21 02:54:12 的主题,其中的信息可能已经有所发展或是发生改变。

    tcpAddr, err := net.ResolveTCPAddr("tcp4", "localhost:8080")

    fmt.Println(err)

    server, e := net.ListenTCP("tcp", tcpAddr)
    fmt.Println(e)
    for {
        conn, _ := server.AcceptTCP()
        util.SetTCPOption(conn)

    }
    tcpConn := conn.(*net.TCPConn)
    tcpConn.SetNoDelay(false)
    tcpConn.SetWriteBuffer(30000)
    tcpConn.SetReadBuffer(30000)

在做数据传输时,设置TCP server,client的接受,发送缓冲区大小时,也开启压缩。 但是在server端,偶尔第一次收到的包,读不够长度, 但是后续包都很正常,不知道哪里有问题,server读的太快了,数据还在路上么? 操作系统windows。另外,因为是并行读,所以用for读满可能会乱序,不考虑 @polaris 大佬,您闲的时候给小弟解惑一下呗

func getPartBody(length int, conn net.Conn) ([]byte){
    buf := make([]byte, length)

    num, _ := conn.Read(buf)

    fmt.Println("read num:", num)

    //TODO recover
    if length != num{
        panic("数据包异常")
    }

    return buf[:num]
}
fun

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

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

1151 次点击  
加入收藏 微博
3 回复  |  直到 2017-12-21 16:23:14
polaris
polaris · #1 · 7年之前

抓包看看呢?

sheepbao
sheepbao · #2 · 7年之前

没读满不是很正常的事吗?tcp只要ack确认了就会给应该层,比如你发送了2000bytes,你客户端可能收到好几次read事件,分别是500,1500bytes,还有可能出现tcp粘包啥的。

leavesdrift
leavesdrift · #3 · 7年之前

tcp是slow-start的,这意味着最开始速率非常低逐渐上升达到阈值之后通过算法控制,具体我记不清楚了,并且tcp设置了nagle算法(一般可以自定义关闭),小包汇聚减少IO次数,所以说tcp是一个不太好揣测的东西。需要良好的自定义协议,封包拆包。但是我觉得slow-start已经够说明为什么第一次buf读不满了,因为底层的io.Reader没有那么多数据可读。

然后因为你说是”第一次“buf读不够,一般如果缓存size小于buf的length,那么这个缓存是失效的,也就是只要底层的io.Reader数据够,那就怎么都会填满。次次除了最后一次都会填满。 如果缓存size大于buf的length,第一次都读不够那就只可能还是io.Reader数据不够,因为数据要先填满缓存。

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