131

I need to create a client-server example over TCP. In the client side I read 2 numbers and I send them to the server. The problem I faced is that I can't convert from []byte to int, because the communication accept only data of type []byte.

Is there any way to convert []byte to int or I can send int to the server?

Some sample code will be really appreciated.

Thanks.

3
  • Just to clarify the task, are you writing both the client and the server code? And are both written in Go? Commented Jun 25, 2012 at 17:10
  • AFAIK you have to do bit shift. Commented Aug 19, 2013 at 22:46
  • To send data to the network it needs to be in byte form. Commented Oct 25, 2014 at 4:43

10 Answers 10

143

You can use encoding/binary's ByteOrder to do this for 16, 32, 64 bit types

Play

package main

import "fmt"
import "encoding/binary"

func main() {
    var mySlice = []byte{244, 244, 244, 244, 244, 244, 244, 244}
    data := binary.BigEndian.Uint64(mySlice)
    fmt.Println(data)
}
Sign up to request clarification or add additional context in comments.

5 Comments

what do you mean by offsets? as in, reading from the middle of a []byte? just do BigEndian.Uint64(bigSlice[10:18]) (basically, read the bytes in the middle of the slice. or do you mean something else?
Ya, I figured after asking the stupid question. Just can't edit it :D Thanks though.
It returns uint16, uint32, unit64 but not int. Need to convert to int from uint
Sort of obvious, but not at first when just wanting to go byte[] to int: this does not work for a case where the byte array is very small. For one of my cases I have a byte array with only 2 elements, and the Uint64 method fails at this line in source _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808, since obviously the index is out of bounds. I needed the Uint16 method.
@TinkalGogoi use int64(value) to convert a value to an int64.
24

If []byte is ASCII byte numbers then first convert the []byte to string and use the strconv package Atoi method which convert string to int.

package main
import (
    "fmt"
    "strconv"
)

func main() {
    byteNumber := []byte("14")
    byteToInt, _ := strconv.Atoi(string(byteNumber))
    fmt.Println(byteToInt)
}

Go playground

2 Comments

parsing an int to a string, then to a byte array and reverse looks like a too long way
Yes, a byte to int would be less expensive but haven't found a way.
13

Starting from a byte array you can use the binary package to do the conversions.

For example if you want to read ints :

buf := bytes.NewBuffer(b) // b is []byte
myfirstint, err := binary.ReadVarint(buf)
anotherint, err := binary.ReadVarint(buf)

The same package allows the reading of unsigned int or floats, with the desired byte orders, using the general Read function.

3 Comments

Varint is specific for protocol buffers and is probably not what you're looking for. Spec: code.google.com/apis/protocolbuffers/docs/encoding.html
Just to clarify, a 32 bit integer may use up to 5 bytes after encoded by Varint.
This doesn't work for the OP's use case. Use binary.Read() instead. See: codereview.stackexchange.com/questions/15945/…
11

The math/big provides a simple and easy way to convert a binary slice to a number playground

package main
import (
    "fmt"
    "math/big"
)
func main() {

    b := []byte{0x01, 0x00, 0x01}

    v := int(big.NewInt(0).SetBytes(b).Uint64())

    fmt.Printf("%v", v)
}

Comments

10
now := []byte{0xFF,0xFF,0xFF,0xFF}
nowBuffer := bytes.NewReader(now)
var  nowVar uint32
binary.Read(nowBuffer,binary.BigEndian,&nowVar)
fmt.Println(nowVar)
4294967295

Comments

6

For encoding/decoding numbers to/from byte sequences, there's the encoding/binary package. There are examples in the documentation: see the Examples section in the table of contents.

These encoding functions operate on io.Writer interfaces. The net.TCPConn type implements io.Writer, so you can write/read directly to network connections.

If you've got a Go program on either side of the connection, you may want to look at using encoding/gob. See the article "Gobs of data" for a walkthrough of using gob (skip to the bottom to see a self-contained example).

2 Comments

Can you give an example of how to use gob in a TCP application?
I've added a link to an article that describes gobs; you can skip to the bottom if you just want to see a code example. When you construct an encoder/decoder, you can just pass in the *TCPConn as the argument to gob.NewEncoder/gob.NewDecoder.
3

Using bitwise operator without additional dependencies

func toInt(bytes []byte) int {
    result := 0
    for i := 0; i < 4; i++ {
        result = result << 8
        result += int(bytes[i])

    }

    return result
}

Comments

2

If bytes in the []byte array are ASCII characters from 0 to 9 you can convert them to an int in a loop:

var value int
for _, b := range []byte{48, 49, 50, 51, 52} {
    value = value*10 + int(b-48)
}
fmt.Printf("integer value: %d", value)

Go Playground

Comments

0

binary.Read in encoding/binary provides mechanisms to convert byte arrays to datatypes.

Note that Network Byte Order is BigEndian, so in this case, you'll want to specify binary.BigEndian.

  package main

  import (
    "bytes"
    "encoding/binary"
    "fmt"
  )

  func main() {
    var myInt int
    b := []byte{0x18, 0x2d} // This could also be a stream
    buf := bytes.NewReader(b)
    err := binary.Read(buf, binary.BigEndian, &myInt) // Make sure you know if the data is LittleEndian or BigEndian
    if err != nil {
        fmt.Println("binary.Read failed:", err)
        return
    }
    fmt.Print(myInt)
  }

Reviewing this documentation may be helpful: https://pkg.go.dev/encoding/[email protected]#Read

Comments

-1

Is there any way to convert []byte to int or I can send int to the server?

A byte in GO is alias for uint8 so there will be a mismatch in sign when you try to convert it to int, since:

uint8 ranges: 0 through 255 and (unsigned and same as byte) However,

int8 ranges: –128 through 127 (signed)

So as a result you would only be able to convert half of the range, and lose the other half which would return 0.

Doing this could understandably result in a loss of data, bugs and it's generally not a good idea.

The best way would be to code your application in a way that respect the datatypes.

    package main

import (
    "fmt"
)

func main() {

    byteslice := []byte{159,127,208,150,211,126,210,192,227,247,240,207,201,36,190,239,79,252,235,104}

    // convert byte to uint8 (it's actually the same)
    fmt.Printf("0x%02X type: %T \n", byteslice[0], byteslice[0])

    byte_0 := byteslice[0]
    fmt.Printf("0x%02X type: %T \n\n", byte_0, byte_0)

    // convert to various bases
    base2  := ""
    base10 := ""
    base16 := ""

    for _, b := range byteslice {

        base2  += fmt.Sprintf("%08b", b) 
        base10 += fmt.Sprintf("%d", b) 
        base16 += fmt.Sprintf("%02X", b) 

    }

    fmt.Printf("base2  %s len %d bits \nbase10 %s \nbase16 %s len %d nibbles \\2 = %d bytes\n",base2, len(base2), base10, base16, len(base16), len(base16)/2)
}

Go Playground

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.