session中read方法實現粘包拆包處理
定義簡單協議,資料報頭由4位元組構成:
第1位固定為』$』
第2-3位為body長度(uint16)
第4位固定為』#』
接收資料時若第1位和第4位不正確則認為接收到異常資料,同時關閉socket連線
本文**檢視github:
為了實現粘包拆包處理,我們自己實現乙個buffer類來管理資料
在server目錄中增加buffer.go,這裡主要參考了
完整**如下
buffer.go
package server
import
("errors"
"io"
)type buffer struct
func
newbuffer
(reader io.reader,
lenint
)*buffer
}func
(instance *buffer)
len(
)int
//cleanbuf 清理快取中已提取的資料
func
(instance *buffer)
cleanbuf()
copy
(instance.buf, instance.buf[instance.start:instance.end]
) instance.end -= instance.start
instance.start =0}
//read 接收資料
func
(instance *buffer)
read()
(int
,error
) instance.end += n
return n,
nil}
//peek 檢視指定長度位元組資料
func
(instance *buffer)
peek
(len
int)([
]byte
,error
) result := instance.buf[instance.start : instance.start+
len]
return result,
nil}
//pick 提取指定長度位元組資料
func
(instance *buffer)
pick
(offset int
,len
int)([
]byte
,error
) instance.start +=
(offset +
len)
return result[offset:],
nil}
session.go 也需要修改
package server
import
("encoding/binary"
"errors"
"net"
"time"
)const
(//headerlen 資料報頭長度
headerlen int=4
//headerstartbyte 資料報頭部起始碼
headerstartbyte byte
='$'
//headerendbyte 資料報頭部結束碼
headerendbyte byte
='#'
)//send 傳送資料
func
send
(buf [
]byte
)//read 讀取資料
//每次讀取必然返回乙個完整資料報或者錯誤資訊
func
read()
([]byte
,error)}
//檢視前4個資料報頭資料
headbuf, err := session.buffer.
peek
(headerlen)
if err !=
nil//判斷1和4位是否為指定的起始碼和結束碼
if headbuf[0]
!= headerstartbyte || headbuf[3]
!= headerendbyte
//計算資料報內容長度
bodylen :=
int(binary.bigendian.
uint16
(headbuf[1:
3]))
//提取資料內容
bodybuf, err := session.buffer.
pick
(headerlen, bodylen)
if err !=
nil//更新最後活躍時間
session.activedatetime = time.
now(
)return bodybuf,
nil}
}
Go實現簡單的Socket服務端筆記 二
第二步 迴圈讀取資料 利用for迴圈,等待客戶端傳送資料 本文 檢視github 修改上一步的 讓服務端迴圈接收客戶端傳送的訊息,主要使用for迴圈,直接上 package main import fmt net func main 程式返回後關閉socket defer tcplistener.c...
Go實現簡單的Socket服務端筆記 三
利用goroutine實現同時多個客戶端連線 將資料讀取放入單獨的方法中,利用goroutine執行 本文 檢視github 要實現多個客戶端連線,需要將每個客戶端放入單獨的執行緒處理,通常我們使用多執行緒實現這個功能,但go語言提供的 goroutine,可以非常方便的實現並行 goroutine...
用go實現簡單的socket通訊
服務端 package main import fmt net func process conn net.conn 3.顯示客戶端傳送的內容到伺服器終端 fmt.println string buf n func main defer listen.close 延時關閉 forelse 這裡準備乙...