package connection import ( "net" ) // NewListen starts listening for a single connection on the given address. // This method blocks until this is done. func NewListen(address string) (*Connection, error) { conn, err := listenAndAcceptTCP(address) if err != nil { return nil, err } return &Connection{ conn: conn, BufSize: defaultBufSize, stopFlag: false, }, nil } func listenAndAcceptTCP(address string) (*net.TCPConn, error) { addr, err := net.ResolveTCPAddr("tcp", address) if err != nil { return nil, err } sock, err := net.ListenTCP("tcp", addr) if err != nil { return nil, err } conn, err := sock.AcceptTCP() if err != nil { return nil, err } conn.SetNoDelay(true) return conn, nil } // RecvChan returns a read-only channel of byte slices and starts // receiving and pushing data into it asynchronously. // The channel is closed when the sender closes the connection. // Use this to read bytes from the network connection. // The data read is owned by the reader, it is thread-safe to modify. func (c *Connection) RecvChan() <-chan []byte { c.dataChan = make(chan []byte) go c.recvLoop() return c.dataChan } func (c *Connection) recvLoop() { buf := make([]byte, c.BufSize) for !c.stopFlag { n, err := c.conn.Read(buf) if err != nil { c.stopFlag = true } if n > 0 { // the underlying memory of the buffer // must be copied for thread safety sendBuf := make([]byte, n) copy(sendBuf, buf) c.dataChan <- sendBuf } } close(c.dataChan) }