TCP粘包与处理

粘包:

  1. 客户端使用nagle算法,将传输的小数据合并
  2. 服务端的接受不及时

golang的处理:
对数据报进行封包和拆包的操作

  • 封包:给一段数据加上包头
  • 拆包,把头部拆掉
    1. // 出现粘包,没有处理粘包现象
    2. func process(conn net.Conn){
    3. defer conn.Close()
    4. reader := bufio.NewReader(conn)
    5. var bug [1024]byte
    6. for {
    7. n,err := reader.Read(buf[:])
    8. if err == io.EOF{
    9. break
    10. }
    11. if err != nil {
    12. fmr.Println("read from client failed")
    13. break
    14. }
    15. recvStr := string(buf[:n])
    16. fmt.Println("收到发送的数据")
    17. }
    18. }
    要处理粘包,要封包。给一段数据加上包头,包头长度固定,存储了包体的大小,这样解析就可以根据胞体长度拆分出一个完整的数据包 ```go func Encode(message string) ([]byte, error){ // 读取消息的长度,转换成int32类型(占4个字节) var length = int32(len(message)) var pkg = new(bytes.Buffer) // 写入消息头 err := binary.Write(pkg, binary.LittleEndian, length) if err != nil {
    1. return nil, err
    } err = binary.Write(pkg, binary.LittleEndian, []byte(message)) if err != nil{
    1. return nil,err
    } }

func Decode(reader *bufio.Reader) (string, error){}

  1. <a name="nmgyN"></a>
  2. # UDP socket
  3. 实时性比较好
  4. ```go
  5. func main(){
  6. listen, err := net.ListenUDP("udp", &net.UDPAddr{
  7. IP: net.IPv4(0,0,0,0),
  8. Port: 30000,
  9. })
  10. if err != nil {
  11. fmr.Println("listen failed, err:", err)
  12. return
  13. }
  14. for (
  15. var data [1024]byte
  16. n, addr, err := listne.ReadFromUDP(data[:]) // 接收数据
  17. if err != nil {
  18. fmt.Println("read failed, err", err)
  19. }
  20. fmt.Println("data:%v addr:%v count:%v\n", string(data[n]), addr, n)
  21. _,err = listen.WriteToUDP(data[:n], addr) // 发送数据
  22. if err != nil {
  23. fmt.Printlen("write to udp failed, err", err)
  24. continue
  25. }
  26. )
  27. }