Go解决TCP粘包

粘包

  • tcp粘包:
    • tcp是流式协议:发送包的时候一次可能没有发完可能给了下一次 nagle算法导致客户端发送的粘包,本意是为了改善客户端网络
  • nagle算法

该算法要求一个tcp连接上最多只能有一个未被确认的未完成的小分组,在该分组ack到达之前不能发送其他的小分组,tcp需要收集这些少量的分组,并在ack到来时以一个分组的方式发送出去;其中小分组的定义是小于MSS的任何分组; 该算法的优越之处在于它是自适应的,确认到达的越快,数据也就发哦送的越快;而在希望减少微小分组数目的低速广域网上,则会发送更少的分组;

  • Nagle算法是以他的发明人John Nagle的名字命名的,它用于自动连接许多的小缓冲器消息;这一过程(称为nagling)通过减少必须发送包的个数来增加网络软件系统的效率。
	if there is new data to send #有数据要发送
        # 发送窗口缓冲区和队列数据 >=mss,队列数据(available data)为原有的队列数据加上新到来的数据
        # 也就是说缓冲区数据超过mss大小,nagle算法尽可能发送足够大的数据包
        if the window size >= MSS and available data is >= MSS 
            send complete MSS segment now # 立即发送
        else
            if there is unconfirmed data still in the pipe # 前一次发送的包没有收到ack
                # 将该包数据放入队列中,直到收到一个ack再发送缓冲区数据
                enqueue data in the buffer until an acknowledge is received 
            else
                send data immediately # 立即发送
            end if
        end if
    end if

https://baike.baidu.com/item/Nagle%E7%AE%97%E6%B3%95

粘包演示

服务端代码

package main

import (
	"fmt"
	"net"
)

func main() {
   
	// 本地端口启动服务
	listener, err := net.Listen("tcp", "localhost:20000")
	if err != nil {
   
		fmt.Println("服务器启动失败....", err)
		return
	}
	fmt.Println("监听成功...")
	// 等待连接
	for {
   
		conn, err := listener.Accept()
		if err != nil {
   
			fmt.Println("连接建立失败...", err)
			break
		}
		fmt.Println("连接成功...")
		go Process
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值