package udp import ( "../com" "bytes" "log" "net" "sync" ) type Connect struct { con *net.UDPConn mutex sync.Mutex logger *log.Logger } func NewConnect(con *net.UDPConn, logger *log.Logger) *Connect { ret := Connect{con: con, logger: logger} return &ret } func (ptr *Connect) Run(packet chan com.Packet) { buffer, cur := bytes.Buffer{}, make([]byte, com.BuffSize) for { n, _, err := ptr.con.ReadFromUDP(cur) if err != nil { packet <- com.Packet{Event: "error"} break } buffer.Write(cur[:n]) for { if index := bytes.Index(buffer.Bytes(), com.SockEndBytes); index != -1 { pool := make([]byte, index+com.SockEndLen) _, e := buffer.Read(pool) if e != nil { ptr.logger.Printf("buffer read error: %s", e) buffer.Reset() } if index = bytes.Index(pool, com.SockStartBytes); index != -1 { pool = pool[index+com.SockStartLen:] index = bytes.Index(pool, com.SockSplitBytes) event, data := string(pool[:index]), pool[index+com.SockSplitLen:len(pool)-com.SockEndLen] packet <- com.Packet{Event: event, Data: data} } } else { break } } } } func parsePacket(packet com.Packet) []byte { message := append(com.SockStartBytes, []byte(packet.Event)...) message = append(message, com.SockSplitBytes...) message = append(message, packet.Data...) message = append(message, com.SockEndBytes...) return message } func (ptr *Connect) Emit(packet com.Packet) { message := parsePacket(packet) ptr.mutex.Lock() _, err := ptr.con.Write(message) ptr.mutex.Unlock() if err != nil { ptr.logger.Printf("Failed to emit on event: %s.", packet.Event) } } func (ptr *Connect) UdpDownEmit(packet com.Packet, addr *net.UDPAddr) { message := parsePacket(packet) ptr.mutex.Lock() _, err := ptr.con.WriteToUDP(message, addr) ptr.mutex.Unlock() if err != nil { ptr.logger.Printf("Failed to emit on event: %s.", packet.Event) } } func (ptr *Connect) Close() { err := ptr.con.Close() if err != nil { ptr.logger.Printf("Fail to close connection: %s", err) } }