网络编程中发送数据的长度 conn.Write 需要接收的是byte数组
func login(userId int, userPwd string) (err error) {//下一步就要开始定协议..//fmt.Printf("userId = %d userPwd = %s\n",userId,userPwd)//return nil//1.链接到服务器conn, err := net.Dial("tcp", "localhost:8889")if err !=
·
func login(userId int, userPwd string) (err error) {
//下一步就要开始定协议..
//fmt.Printf("userId = %d userPwd = %s\n",userId,userPwd)
//return nil
//1.链接到服务器
conn, err := net.Dial("tcp", "localhost:8889")
if err != nil {
fmt.Println("net.Dial err=", err)
return
}
//延时关闭
defer conn.Close()
//2.准备通过conn发送消息给服务器
var mes message.Message
mes.Type = message.LoginMesType
//3.创建一个LoginMes结构体
var loginMes message.LoginMes
loginMes.UserId = userId
loginMes.UserPwd = userPwd
//4.将loginMes序列化
data, err := json.Marshal(loginMes)
if err != nil {
fmt.Println("json.Marshal err= ", err)
return
}
//5.将data赋给mes.Data字段
mes.Data = string(data)
//type Message struct {
//Type string `json:"type"`//消息类型
//Data string `json:"data"`//消息的内容
//}
//6.将mes进行序列化 最后这个数据就是我们要发送的数据了 他是一个byte切片
data, err = json.Marshal(mes)
if err != nil {
fmt.Println("json.Marshal err= ", err)
return
}
//7.到这个时候 data就是我们要发送的消息
//7.1先把data的长度发送给服务器
//而conn.Write接受的数据类型是byte切片,所以首先要获取到data的长度->转成一个表示长度的byte切片
var pkglen uint32 //先定义包的长度,因为他说一会要发送的所以定义成unit32类型的,使用type ByteOrder来转换成byte类型的
pkglen = uint32(len(data))
var buf [4]byte
binary.BigEndian.PutUint32(buf[0:4], pkglen)
//现在就可以发送了
n, err := conn.Write(buf[:4])
if n != 4 || err != nil {
fmt.Println("conn.Write(bytes) fail", err)
return
}
fmt.Println("客户端发送的消息长度成功")
return
}
var pkglen uint32 //先定义包的长度,因为他说一会要发送的所以定义成unit32类型的,使用type
//ByteOrder来转换成byte类型的
pkglen = uint32(len(data))
//因为conn.Write的接受的数据类型是byte数组,而
//binary.BigEndian.PutUint32,需要将unit型的才能转为byte数组
var buf [4]byte
binary.BigEndian.PutUint32(buf[0:4], pkglen)
//现在就可以发送了
n, err := conn.Write(buf[:4])
Conn的官方文档,Write(b []byte) (n int, err error)
type Conn
type Conn interface {
// Read从连接中读取数据
// Read方法可能会在超过某个固定时间限制后超时返回错误,该错误的Timeout()方法返回真
Read(b []byte) (n int, err error)
// Write从连接中写入数据
// Write方法可能会在超过某个固定时间限制后超时返回错误,该错误的Timeout()方法返回真
Write(b []byte) (n int, err error)
// Close方法关闭该连接
// 并会导致任何阻塞中的Read或Write方法不再阻塞并返回错误
Close() error
// 返回本地网络地址
LocalAddr() Addr
// 返回远端网络地址
RemoteAddr() Addr
// 设定该连接的读写deadline,等价于同时调用SetReadDeadline和SetWriteDeadline
// deadline是一个绝对时间,超过该时间后I/O操作就会直接因超时失败返回而不会阻塞
// deadline对之后的所有I/O操作都起效,而不仅仅是下一次的读或写操作
// 参数t为零值表示不设置期限
SetDeadline(t time.Time) error
// 设定该连接的读操作deadline,参数t为零值表示不设置期限
SetReadDeadline(t time.Time) error
// 设定该连接的写操作deadline,参数t为零值表示不设置期限
// 即使写入超时,返回值n也可能>0,说明成功写入了部分数据
SetWriteDeadline(t time.Time) error
}
使用binary的ByteOrder进行数据类型的转换
package binary
import "encoding/binary"
binary包实现了简单的数字与字节序列的转换以及变长值的编解码。
type ByteOrder
type ByteOrder interface {
Uint16([]byte) uint16
Uint32([]byte) uint32
Uint64([]byte) uint64
PutUint16([]byte, uint16)
PutUint32([]byte, uint32)
PutUint64([]byte, uint64)
String() string
}
ByteOrder规定了如何将字节序列和 16、32或64比特的无符号整数互相转化。
更多推荐
已为社区贡献6条内容
所有评论(0)