我试图在golang中通过TCP发送int64,但是,我的接收器打印得到的数字与我发出的数字不同。实现这个目标的正确方法是什么?
//Buffer on both client and server
buffer := make([]byte, 1024)
//Sender
fileInfo, error := os.Stat(fileName)
if error != nil {
fmt.Println("Error opening file")
}
var fSize int = int(fileInfo.Size())
connection.Write([]byte(string(fSize)))
//Receiver
connection.Read(buffer)
fileSize := new(big.Int).SetBytes(bytes.Trim(buffer, "\x00")).Int64()
if err != nil {
fmt.Println("not a valid filesize")
fileSize = 0
}
答案 0 :(得分:6)
使用binary.Write
/ binary.Read
:
//sender
err := binary.Write(connection, binary.LittleEndian, fileInfo.Size())
if err != nil {
fmt.Println("err:", err)
}
//receiver
var size int64
err := binary.Read(connection, binary.LittleEndian, &size)
if err != nil {
fmt.Println("err:", err)
}
[]byte(string(fSize))
没有做你认为它做的事情,它将数字视为unicode字符,它不会返回它的字符串表示。
如果你想要一个数字的字符串表示,使用strconv.Itoa
,如果你想要二进制表示,那么使用:
num := make([]byte, 8) // or 4 for int32 or 2 for int16
binary.LittleEndian.PutUint64(num, 1<<64-1)
答案 1 :(得分:1)
使用binary.BigEndian或binary.LittleEndian对整数进行编码:
var size int64
// Send
var buf [8]byte
binary.BigEndian.PutUint64(buf[:], uint64(size))
_, err := w.Write(buf[:])
// Receive
var buf [8]byte
_, err := io.ReadFull(r, buf[:])
if err != nil {
// handle error
}
size = int64(binary.BigEndian.Uint64(buf[:])
您还可以使用binary.Read和binary.Write。您的应用程序代码将以类型开关和这些函数中的其他goo为代价稍微缩短。
关于问题代码的几点意见。转换
string(fSize)
返回符文fSize的UTF-8表示。它不返回十进制编码或二进制编码值。使用strconv packate将数值转换为十进制表示。使用上面提到的二进制包转换为二进制表示。
序列
connection.Read(buffer)
buffer = bytes.Trim(buffer, "\x00")
如果数据在末尾包含0字节,则删除实际数据。 Read返回读取的字节数。使用该长度来切片缓冲区:
n, err := connection.Read(buffer)
buffer = buffer[:n]
答案 2 :(得分:0)
你不能使用string()从int转换,你需要使用strconv包。
connection.Write([]byte(strconv.FormatInt(fileInfo.Size(), 10))