package tcp import ( "bufio" "net" "time" ) func errTimeout(err error) bool { if opErr, ok := err.(*net.OpError); ok { if opErr.Temporary() || opErr.Timeout() { return true } } return false } // Write tcp write func Write(conn *net.TCPConn, timeout time.Duration, data []byte) (n int, isTimeout bool, err error) { conn.SetWriteDeadline(time.Now().Add(timeout)) n, err = conn.Write(data) if err != nil { isTimeout = errTimeout(err) } return } // Read tcp reads data into p. // It returns the number of bytes read into p. // The bytes are taken from at most one Read on the underlying Reader, // hence n may be less than len(p). // To read exactly len(p) bytes, use io.ReadFull(b, p). // At EOF, the count will be zero and err will be io.EOF. func Read(conn *net.TCPConn, timeout time.Duration, p []byte) (n int, isTimeout bool, err error) { buffer := bufio.NewReader(conn) conn.SetReadDeadline(time.Now().Add(timeout)) n, err = buffer.Read(p) if err != nil { isTimeout = errTimeout(err) } return } // ReadBytes tcp reads until the first occurrence of delim in the input, // returning a slice containing the data up to and including the delimiter. // If ReadBytes encounters an error before finding a delimiter, // it returns the data read before the error and the error itself (often io.EOF). // ReadBytes returns err != nil if and only if the returned data does not end in // delim. // For simple uses, a Scanner may be more convenient. func ReadBytes(conn *net.TCPConn, timeout time.Duration, delim byte) (data []byte, isTimeout bool, err error) { buffer := bufio.NewReader(conn) conn.SetReadDeadline(time.Now().Add(timeout)) data, err = buffer.ReadBytes(delim) if err != nil { isTimeout = errTimeout(err) } return } // Optimize TCP connect optimize func Optimize(conn *net.TCPConn) (err error) { err = conn.SetNoDelay(true) if err != nil { return } err = conn.SetKeepAlive(true) if err != nil { return } err = conn.SetKeepAlivePeriod(3 * time.Minute) return }