2021-04-07 粘包改写

server

//服务端解包过程
package main

import (
   "fmt"
   "net"
   "nianbao/protocol"
   "os"
)

func main() {
   netListen, err := net.Listen("tcp", ":9988")
   CheckError(err)

   defer netListen.Close()

   Log("Waiting for clients")
   for {
      conn, err := netListen.Accept()
      if err != nil {
         continue
      }

      Log(conn.RemoteAddr().String(), " tcp connect success")
      go handleConnection(conn)
   }
   //fmt.Println("dd")
}

func handleConnection(conn net.Conn) {
   //声明一个临时缓冲区,用来存储被截断的数据
   tmpBuffer := make([]byte, 0)

   //声明一个管道用于接收解包的数据
   readerChannel := make(chan []byte, 16)
   go reader(readerChannel)

   buffer := make([]byte, 1500)

   for {
      n, err := conn.Read(buffer)
      if err != nil {
         Log(conn.RemoteAddr().String(), " connection error: ", err)
         return
      }

      tmpBuffer = protocol.Unpack(append(tmpBuffer, buffer[:n]...), readerChannel)
   }
}

func reader(readerChannel chan []byte) {
   for {
      select {
      case data := <-readerChannel:
         Log(string(data))
      }
   }
}

func Log(v ...interface{}) {
   fmt.Println(v...)
}

func CheckError(err error) {
   if err != nil {
      fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
      os.Exit(1)
   }
}

 

client

//客户端发送封包
package main

import (
   "fmt"
   "net"
   "nianbao/protocol"
   "os"
   "time"
)

func sender(conn net.Conn) {
   for i := 0; i < 1000; i++ {
      words := "<?xml version=\"1.0\"?>\n<Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <Header>\n    <MessageName>FoSecurityResult</MessageName>\n    <MessageTime>2021-03-31T15:02:37+08:00</MessageTime>\n  </Header>\n  <Body>\n    <Record>\n      <CheckType>1</CheckType>\n      <CheckId>3999205072</CheckId>\n      <ImageGuid>f55ce2cc43914aeabd828986904f3eed_NUCTECH00120210331000222</ImageGuid>\n      <DeviceId>f55ce2cc43914aeabd828986904f3eed</DeviceId>\n      <CheckPos>T2G1</CheckPos>\n      <Result>R</Result>\n      <Department>0</Department>\n      <OptId>n7</OptId>\n      <Image2DUrl>http://10.37.38.5:1002/202103313999205072/1/150221_000222.jpg</Image2DUrl>\n      <Image3DUrl>http://10.37.38.5:1002/202103313999205072/1/150221_000222_3D.jpg</Image3DUrl>\n      <SideImage2DUrl>http://10.37.38.5:1002/202103313999205072/1/150221_000222_side.jpg</SideImage2DUrl>\n      <TaggedImage2DUrl>http://10.37.38.5:1002/202103313999205072/1/150221_000222_2DManualMark.jpg</TaggedImage2DUrl>\n      <TaggedSideImage2DUrl>http://10.37.38.5:1002/202103313999205072/1/150221_000222_2DManualMark_side.jpg</TaggedSideImage2DUrl>\n      <TaggedImage3DUrl>http://10.37.38.5:1002/202103313999205072/1/150221_000222_3DManualMark.jpg</TaggedImage3DUrl>\n      <CreateTime>2021-03-31T15:02:21+08:00</CreateTime>\n      <CheckTime>2021-03-31T15:02:37+08:00</CheckTime>\n    </Record>\n  </Body>\n</Envelope><?xml version=\"1.0\"?>\n<Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <Header>\n    <MessageName>FoSecurityResult</MessageName>\n    <MessageTime>2021-03-31T15:02:37+08:00</MessageTime>\n  </Header>\n  <Body>\n    <Record>\n      <CheckType>1</CheckType>\n      <CheckId>3999101496</CheckId>\n      <ImageGuid>c193d6034c3b49d69323e306735da0f0_NUCTECH00120210331000318</ImageGuid>\n      <DeviceId>c193d6034c3b49d69323e306735da0f0</DeviceId>\n      <CheckPos>T1C1</CheckPos>\n      <Result>C</Result>\n      <Department>0</Department>\n      <OptId>n4</OptId>\n      <Image2DUrl>http://10.37.38.5:1002/202103313999101496/1/150220_000318.jpg</Image2DUrl>\n      <Image3DUrl>http://10.37.38.5:1002/202103313999101496/1/150220_000318_3D.jpg</Image3DUrl>\n      <SideImage2DUrl>http://10.37.38.5:1002/202103313999101496/1/150220_000318_side.jpg</SideImage2DUrl>\n      <TaggedImage2DUrl>http://10.37.38.5:1002/202103313999101496/1/150220_000318_2DManualMark.jpg</TaggedImage2DUrl>\n      <TaggedSideImage2DUrl>http://10.37.38.5:1002/202103313999101496/1/150220_000318_2DManualMark_side.jpg</TaggedSideImage2DUrl>\n      <TaggedImage3DUrl>http://10.37.38.5:1002/202103313999101496/1/150220_000318_3DManualMark.jpg</TaggedImage3DUrl>\n      <CreateTime>2021-03-31T15:02:20+08:00</CreateTime>\n      <CheckTime>2021-03-31T15:02:37+08:00</CheckTime>\n    </Record>\n  </Body>\n</Envelope><?xml version=\"1.0\"?>\n<Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <Header>\n    <MessageName>FoSecurityResult</MessageName>\n    <MessageTime>2021-03-31T15:02:38+08:00</MessageTime>\n  </Header>\n  <Body>\n    <Record>\n      <CheckType>1</CheckType>\n      <CheckId>3999102398</CheckId>\n      <ImageGuid>b4a29b573be24d5590dd5b2fb6183685_NUCTECH00120210331000155</ImageGuid>\n      <DeviceId>b4a29b573be24d5590dd5b2fb6183685</DeviceId>\n      <CheckPos>T1D2</CheckPos>\n      <Result>C</Result>\n      <Department>0</Department>\n      <OptId>n8</OptId>\n      <Image2DUrl>http://10.37.38.5:1002/202103313999102398/1/150221_000155.jpg</Image2DUrl>\n      <Image3DUrl>http://10.37.38.5:1002/202103313999102398/1/150221_000155_3D.jpg</Image3DUrl>\n      <SideImage2DUrl>http://10.37.38.5:1002/202103313999102398/1/150221_000155_side.jpg</SideImage2DUrl>\n      <TaggedImage2DUrl xsi:nil=\"true\" />\n      <TaggedSideImage2DUrl xsi:nil=\"true\" />\n      <TaggedImage3DUrl xsi:nil=\"true\" />\n      <CreateTime>2021-03-31T15:02:21+08:00</CreateTime>\n      <CheckTime>2021-03-31T15:02:37+08:00</CheckTime>\n    </Record>\n  </Body>\n</Envelope>"
      conn.Write(protocol.Packet([]byte(words)))
      //words2 := "<?xmlId:111111:end?><?xmlId:123456:end?>"

      //words2 := "333333444444555555666666777777888888999999000000:end?>"
      //conn.Write(protocol.Packet([]byte(words2)))
   }
   fmt.Println("send over")
}

func main() {
   server := "127.0.0.1:9988"
   tcpAddr, err := net.ResolveTCPAddr("tcp4", server)
   if err != nil {
      fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
      os.Exit(1)
   }

   conn, err := net.DialTCP("tcp", nil, tcpAddr)
   if err != nil {
      fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
      os.Exit(1)
   }

   defer conn.Close()
   fmt.Println("connect success")
   go sender(conn)
   for {
      time.Sleep(1 * 1e9)
   }
}

 

 

package protocol

import (
   "bytes"
   "encoding/binary"
   "fmt"
)

const (
   ConstHeader         = "www.01happy.com"
   ConstHeaderLength   = 15
   ConstSaveDataLength = 4
   ConstXMLHeader      = "<?xml"
   ConstXMLEnder       = "</Envelope>"
   ConstXMLHeaderLen   = 5
   ConstXMLEnderLen    = 11
)

//封包
func Packet(message []byte) []byte {
   //fmt.Println(string(message))
   return message

   //return append(append([]byte(ConstHeader), IntToBytes(len(message))...), message...)
}

//解包
func Unpack(buffer []byte, readerChannel chan []byte) []byte {
   length := len(buffer)
   var end int
   var i int
   for i = 0; i < length; i = i + 1 {
      if length < i+ConstXMLHeaderLen {
         break
      }
      if string(buffer[i:i+ConstXMLHeaderLen]) == ConstXMLHeader {
         for j := i + ConstXMLHeaderLen; j < length; j = j + 1 {
            if length < j+ConstXMLHeaderLen {
               data := buffer[i:]
               fmt.Println("AAAA",data)
               return buffer[i:]
            }
            if string(buffer[j:j+ConstXMLEnderLen]) == ConstXMLEnder {
               end = j + ConstXMLEnderLen

               data := buffer[i:end]
               //fmt.Println("放入chan",data)
               readerChannel <- data

               i = end - 1
               break
            }

         }
      }
   }

   if i == length {
      return make([]byte, 0)
   }
   return buffer[i:]
}

//解包
func Unpack2(buffer []byte, readerChannel chan []byte) []byte {
   length := len(buffer)

   var i int
   for i = 0; i < length; i = i + 1 {
      if length < i+ConstHeaderLength+ConstSaveDataLength {
         break
      }
      if string(buffer[i:i+ConstHeaderLength]) == ConstHeader {
         messageLength := BytesToInt(buffer[i+ConstHeaderLength : i+ConstHeaderLength+ConstSaveDataLength])
         if length < i+ConstHeaderLength+ConstSaveDataLength+messageLength {
            break
         }
         data := buffer[i+ConstHeaderLength+ConstSaveDataLength : i+ConstHeaderLength+ConstSaveDataLength+messageLength]
         readerChannel <- data

         i += ConstHeaderLength + ConstSaveDataLength + messageLength - 1
      }
   }

   if i == length {
      return make([]byte, 0)
   }
   return buffer[i:]
}

//整形转换成字节
func IntToBytes(n int) []byte {
   x := int32(n)

   bytesBuffer := bytes.NewBuffer([]byte{})
   binary.Write(bytesBuffer, binary.BigEndian, x)
   return bytesBuffer.Bytes()
}

//字节转换成整形
func BytesToInt(b []byte) int {
   bytesBuffer := bytes.NewBuffer(b)

   var x int32
   binary.Read(bytesBuffer, binary.BigEndian, &x)

   return int(x)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值