package meanstoanend import ( "encoding/binary" "errors" "io" "net" "github.com/charmbracelet/log" ) type message struct { a int32 b int32 } type client struct { conn net.Conn prices map[int32]int32 log *log.Logger buf []byte } func (c *client) handleMessage() error { _, err := io.ReadFull(c.conn, c.buf) if err != nil { return err } msg := new(message) _, err = binary.Decode(c.buf[1:5], binary.BigEndian, &msg.a) if err != nil { return err } _, err = binary.Decode(c.buf[5:], binary.BigEndian, &msg.b) if err != nil { return err } switch c.buf[0] { case 'I': c.prices[msg.a] = msg.b case 'Q': var i int64 var mean int64 for k, v := range c.prices { if k >= msg.a && k <= msg.b { mean += int64(v) i += 1 } } if i > 0 { mean /= i } binary.Write(c.conn, binary.BigEndian, int32(mean)) default: c.conn.Close() return errors.New("bad message") } return nil } func acceptConn(conn net.Conn) { log.Info("accepting connection", "remote", conn.RemoteAddr()) var err error c := new(client) c.log = log.Default().WithPrefix(conn.RemoteAddr().String()) c.buf = make([]byte, 9) c.conn = conn c.prices = map[int32]int32{} defer c.conn.Close() for { c.log.Debug("waiting for message", "remote", conn.RemoteAddr()) err = c.handleMessage() if err != nil { if err != io.EOF { c.log.Error("unable to read data", "err", err) } break } } c.log.Info("released connection") } func New(listener net.Listener) error { for { conn, err := listener.Accept() if err != nil { return err } go acceptConn(conn) } }