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