在go中通过套接字发送int64的正确方法

时间:2014-09-27 01:10:26

标签: tcp go

我试图在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
}

3 个答案:

答案 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.BigEndianbinary.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.Readbinary.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))