package connection
import (
"encoding/binary"
"errors"
"io"
"net"
"sync"
"time"
)//支援的最大訊息長度
const maxlength int = 1
<<32 - 1
// 4294967295
var (
rheadbytes = [4]byte
wheadbytes = [4]byte
errmsgread = errors.new("message read length error")
errheadlen = errors.new("message head length error")
errmsglen = errors.new("message length is no longer in normal range")
)var connpool sync.pool
//從物件池中獲取乙個物件,不存在則申明
func newconnection(conn net.conn) conn
return &connection
}type conn inte***ce
//定義乙個結構體,用來封裝conn.
type connection struct
//此方法用來讀取頭部訊息.
func (self *connection) rhead() error
return errheadlen
}self
.rlen = int(binary.bigendian
.uint32(rheadbytes[:]))
return
nil}
//此方法用來傳送頭訊息
func (self *connection) whead(l int) error
binary.bigendian
.putuint32(wheadbytes[:], uint32(l))
_, err := self
.rwc
.write(wheadbytes[:])
return err
}//頭部訊息解析之後.返回乙個io.reader藉口.用來讀取遠端傳送過來的資料
//封裝成limitread物件.來實現ioreader介面
func (self *connection) read() (r io.reader, size int, err error)
size = self
.rlen
r = limitread
return
}//傳送訊息前先呼叫whead函式,來傳送頭部資訊,然後傳送body
func (self *connection) write(p byte) (n int, err error)
n, err = self
.rwc
.write(p)
self
.wlock
.unlock()
return
}//傳送乙個流.必須指定流的長度
func (self *connection) writer(size int, r io.reader) (n int64, err error)
n, err = io.copyn(self
.rwc, r, int64(size))
self
.wlock
.unlock()
return
}func (self *connection) remoteaddr() net.addr
func (self *connection) localaddr() net.addr
func (self *connection) setdeadline(t time.time) error
func (self *connection) setreaddeadline(t time.time) error
func (self *connection) setwritedeadline(t time.time) error
func (self *connection) close() (err error)
type limitread struct
func (self limitread) read(p byte) (n int, err error)
return n, err
}
測試函式方法:
package connection
import (
"fmt"
"io"
"net"
"os"
"testing"
"time"
)func test_conn(t *testing.t)
func dial()
c := newconnection(conn)
defer c.close()
c.write(byte("test"))
c.write(byte("test"))
r, size, err := c.read()
if err != nil
_, err = io.copy(os.stdout, r)
if err != nil && err != io.eof
}func listener(proto, addr string)
defer lis.close()
for
go handler(conn)
}}func handler(conn net.conn) )
defer c.close()
gofunc(ch chan
struct{}) (msgchan)
for
n, err := io.copy(os.stdout, r)
if err != nil || n != int64(size)
fmt.println("讀取資料失敗:", err)
return
}time.sleep(2e9)
msgchan <- struct{}{}
}}
Golang 17 遞迴函式
遞迴,就是在執行的過程中呼叫自己。語法格式如下 func recursion func main go 語言支援遞迴。但我們在使用遞迴時,開發者需要設定退出條件,否則遞迴將陷入無限迴圈中。遞迴函式對於解決數學上的問題是非常有用的,就像計算階乘,生成斐波那契數列等。以下例項通過 go 語言的遞迴函式實...
golang的tcp程式設計
server端 package main import fmt net func main defer listener.close 說明accept是在監聽 fmt.println 等待客戶端建立鏈結 conn,err listener.accept conn.write byte 來自服務端的訊...
TCP的互動資料流
在 tcp進行資料傳輸時 可以分為成塊資料流和互動資料流兩種 且處理的 演算法不同.每乙個互動按鍵都會產生乙個分組,也就是說,每次從客戶傳到伺服器的是乙個位元組的按鍵 而不是每次一行 報文段2可以和報文段3進行合併 按鍵確認和按鍵回顯一起傳送 按鍵確認和按鍵回顯兩個報文段合併在一起傳送,這種技術叫做...