具体实现
由于篇幅的限制,此处没有贴出客户端实现的具体代码,细节请查看项目地址。
数据传输格式
我们需要定义服务端与客户端交互的数据格式。
type Data struct {
Name string // service name
Args []interface{} // request's or response's body except error
Err string // remote server error
}
与交互数据相对应的编码与解码函数。
func encode(data Data) ([]byte, error) {
var buf bytes.Buffer
encoder := gob.NewEncoder(&buf)
if err := encoder.Encode(data); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func decode(b []byte) (Data, error) {
buf := bytes.NewBuffer(b)
decoder := gob.NewDecoder(buf)
var data Data
if err := decoder.Decode(&data); err != nil {
return Data{}, err
}
return data, nil
}
同时,我们需要定义简单的 TLV 协议(固定长度消息头 + 变长消息体),规范数据的传输。
// Transport struct
type Transport struct {
conn net.Conn
}
// NewTransport creates a transport
func NewTransport(conn net.Conn) *Transport {
return &Transport{conn}
}
// Send data
func (t *Transport) Send(req Data) error {
b, err := encode(req) // Encode req into bytes
if err != nil {
return err
}
buf := make([]byte, 4+len(b))
binary.BigEndian.PutUint32(buf[:4], uint32(len(b))) // Set Header field
copy(buf[4:], b) // Set Data field
_, err = t.conn.Write(buf)
return err
}
// Receive data
func (t *Transport) Receive() (Data, error) {
header := make([]byte, 4)
_, err := io.ReadFull(t.conn, header)
if err != nil {
return Data{}, err
}
dataLen := binary.BigEndian.Uint32(header) // Read Header filed
data := make([]byte, dataLen) // Read Data Field
_, err = io.ReadFull(t.conn, data)
if err != nil {
return Data{}, err
}
rsp, err := decode(data) // Decode rsp from bytes
return rsp, err
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。









