TCP粘包问题
什么是TCP粘包
TCP粘包就是指发送方发送的若干数据包到达接受方时粘成了一包。从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾。
为什么会出现粘包主要原因就是TCP数据传递模式是流模式,在保持长连接的时候可以进行多次的收和发。
粘包可发生在发送端也可以发生在接收端:
- 发送端:由Nagle算法导致的粘包。Nagle算法是一种改善网络传输效率的算法。这个算法简单来说,就是当我们提交一段数据给TCP发送时,TCP并不会立刻发送这段数据,而是等待一小段时间卡看看在等待期间是否还有要发送的数据,若有则会一次把两段数据合并成一个大的数据块,进行封包,发送出去。
- 接收端:由于接收端接收不及时造成的粘包。TCP会把接收到的数据存在自己的缓冲区内,然后通知应用层取数据。当应用层由于某些原因不能及时的把TCP的数据取出来,就会造成TCP缓冲区存放了几段数据。
Server端:
package main
import (
"bufio"
"fmt"
"io"
"net"
"os"
)
func ServerHandlerErr(err error, where string){
if err != nil{
fmt.Println(err, where)
os.Exit(1)
}
}
func Processmsg(conn net.Conn){
defer conn.Close()
buff := make([]byte, 1024)
reader := bufio.NewReader(conn)
for{
n, err := reader.Read(buff)
if err != nil{
fmt.Println("Read from client failed,error is ", err)
break
}
if err == io.EOF{
break
}
recvStr := string(buff[0:n])
fmt.Println("Read from client message: ", recvStr)
}
}
func main(){
listen, err := net.Listen("tcp", "127.0.0.1:20000")
ServerHandlerErr(err, "net.Listen")
defer listen.Close()
for{
conn, listenerr := listen.Accept()
if listenerr != nil{
fmt.Println("accept failed,error is: ", listenerr)
continue
}
go Processmsg(conn)
}
}
Cilent端:
package main
import (
"fmt"
"net"
)
func main(){
conn, err := net.Dial("tcp", "127.0.0.1:20000")
if err != nil{
fmt.Println("dial failed, err: ", err)
return
}
defer conn.Close()
for i := 0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?