|  | @@ -0,0 +1,75 @@
 | 
	
		
			
				|  |  | +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
 | 
	
		
			
				|  |  | +}
 |