Browse Source

TCP io & optimize

ls 4 years ago
parent
commit
8ed4481759
1 changed files with 75 additions and 0 deletions
  1. 75 0
      tcp/io.go

+ 75 - 0
tcp/io.go

@@ -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
+}