package main import ( "bufio" "fmt" "net" "strconv" "strings" "time" ) type client struct { Conn net.Conn Payload string DeviceID string Plen int //包长度 ver string //版本 step bool //计步开关 find bool //发现开关 phb string //电话本 sms string //短消息 cr string //定位 } func (m *client) unpack() { str := strings.Split(m.Payload, "*") m.DeviceID = str[1] l, err := strconv.Atoi(str[2]) if err == nil { m.Plen = l } m.Payload = strings.TrimRight(str[3], "]") } func (m *client) pack() string { return fmt.Sprintf("[3G*%s*%04d*%s]", m.DeviceID, len(m.Payload), m.Payload) } var messageChan chan *client var platfromChan chan *client var devices map[string]*client func init() { messageChan = make(chan *client) platfromChan = make(chan *client) devices = make(map[string]*client) } func main() { go processPlatfrom() go messageWrite() listen, err := net.Listen("tcp", "0.0.0.0:8080") if err != nil { fmt.Println("Listen() failed, err: ", err) return } for { conn, err := listen.Accept() if err != nil { fmt.Println("Accept() failed, err: ", err) continue } go processClient(conn) } } func processClient(conn net.Conn) { defer conn.Close() for { reader := bufio.NewReader(conn) var buf [128]byte n, err := reader.Read(buf[:]) if err != nil { fmt.Println("read from client failed, err: ", err) break } mess := &client{ Conn: conn, Payload: string(buf[:n]), } messageChan <- mess } } func messageWrite() { for { select { case msg := <-messageChan: if processContent(msg) { n, err := msg.Conn.Write([]byte(msg.pack())) if err != nil { fmt.Printf("%s[%s] reply write[%d]: %v\n", msg.DeviceID, msg.Conn.RemoteAddr(), n, err) continue } fmt.Printf("%s[%s] reply write[%d]: %s\n", msg.DeviceID, msg.Conn.RemoteAddr(), n, msg.Payload) } case msg := <-platfromChan: n, err := msg.Conn.Write([]byte(msg.pack())) if err != nil { fmt.Printf("%s[%s] platfrom write[%d]: %v\n", msg.DeviceID, msg.Conn.RemoteAddr(), n, err) continue } fmt.Printf("%s[%s] platfrom write[%d]: %s\n", msg.DeviceID, msg.Conn.RemoteAddr(), n, msg.Payload) } time.Sleep(5 * time.Microsecond) } } func processContent(c *client) bool { reply := false c.unpack() fmt.Printf("%s[%s] read: %s\n", c.DeviceID, c.Conn.RemoteAddr().String(), c.Payload) content := strings.Split(c.Payload, ",") switch content[0] { case "LK": c.Payload = "LK" reply = true case "TKQ": case "VERNO": c.ver = content[1] case "MESSAGE": c.sms = "ok" case "PEDO": c.step = true case "WALKTIME": c.step = true case "PHB": c.phb = "ok" case "CR": c.cr = "ok" } devices[c.DeviceID] = c return reply } func processPlatfrom() { for { for _, c := range devices { if c.ver == "" { platfromChan <- &client{ Conn: c.Conn, DeviceID: c.DeviceID, Payload: "VERNO", } continue } //定位 if c.cr == "" { platfromChan <- &client{ Conn: c.Conn, DeviceID: c.DeviceID, Payload: "CRa", } continue } if c.sms == "" { platfromChan <- &client{ Conn: c.Conn, DeviceID: c.DeviceID, Payload: "MESSAGE,597D003100320033", } continue } if c.phb == "" { // n1 := strconv.QuoteToASCII("爸爸") platfromChan <- &client{ Conn: c.Conn, DeviceID: c.DeviceID, Payload: "PHB,13967898042,a,13967898042,b,13967898042,c,13967898042,d,13967898042,e", } continue } //查找手表(通过) if !c.find { platfromChan <- &client{ Conn: c.Conn, DeviceID: c.DeviceID, Payload: "FIND", } continue } //计步通不过 if !c.step { platfromChan <- &client{ Conn: c.Conn, DeviceID: c.DeviceID, Payload: "PEDO,1", } platfromChan <- &client{ Conn: c.Conn, DeviceID: c.DeviceID, Payload: "WALKTIME,00:00-23:59", } continue } } time.Sleep(5 * time.Second) } }