package network import ( "net" "bet24.com/log" "bet24.com/public" ) const ( HEADER uint8 = 0xAA CMD_PING uint8 = 5 MAX_BUFFER_SIZE int = 4096 ) type DataLink struct { recvBuffer []byte } func NewDataLink() *DataLink { var obj = new(DataLink) obj.recvBuffer = nil return obj } func (this *DataLink) OnDataArrive(buffer []byte, onCommand func([]byte)) bool { if buffer == nil { return true } if this.recvBuffer != nil { if buffer != nil { buffer = append(this.recvBuffer, buffer...) } else { buffer = this.recvBuffer } this.recvBuffer = nil } totalLen := len(buffer) if totalLen == 0 { return true } // 不够包头 if totalLen < 4 { this.appendTemBuffer(buffer) return true } // 解析长度 var ba *public.ByteArray = public.CreateByteArray(buffer) ph, _ := ba.ReadUInt8() if ph != HEADER { log.Debug("handleData 第一个字节不是%d %d\n", HEADER, ph) return false } cmdID, _ := ba.ReadUInt8() cmdLen, _ := ba.ReadUInt16() if ba.Available() < int(cmdLen) { // 粘包 this.appendTemBuffer(buffer) return true } log.Debug("handleData cmdID = %d,cmdLen = %d,totalLen = %d", cmdID, cmdLen, totalLen) // 是否第一个包 cmdBuffer := make([]byte, cmdLen+1) cmdBuffer[0] = cmdID ba.ReadBytes(cmdBuffer, int(cmdLen), 1) onCommand(cmdBuffer) nAvailable := ba.Available() if nAvailable > 0 { available := make([]byte, nAvailable) ba.ReadBytes(available, nAvailable, 0) this.appendTemBuffer(available) return this.OnDataArrive([]byte{}, onCommand) } return true } func (this *DataLink) appendTemBuffer(buffer []byte) { if this.recvBuffer == nil { this.recvBuffer = buffer[:] return } this.recvBuffer = append(this.recvBuffer, buffer...) } func SendData(data []byte, conn net.Conn) { log.Debug("datalink SendData len = %d", len(data)) var buf []byte var ba *public.ByteArray = public.CreateByteArray(buf) dataLen := 0 if data != nil { dataLen = len(data) } ba.WriteUInt8(HEADER) ba.WriteUInt8(0) ba.WriteInt16(int16(dataLen)) if data != nil { ba.WriteBytes(data) } conn.Write(ba.Bytes()) }