Send a single byte net.Conn Go - go

I've got a Go TCP server which accepts connections, I'd like to echo the messages back 1 byte at a time, I can't see a way to get net.Conn to send a single byte using net.Conn.Write
c.Write([]byte(b))
cannot convert b (type byte) to type []byte
c.Write(b)
cannot use b (type byte) as type []byte in argument to c.Write

an io.Writer always accepts a []byte as the argument. Use a 1 byte long byte slice. What you tried ([]byte(b)) was to convert a single byte to a byte slice. Instead, create a one-element byte slice with b as the only element:
n, err := c.Write([]byte{b})

Use b[i:i+1] to create a one byte slice:
s := "Hello world!"
b := []byte(s)
for i:=0; i<len(s); i++ {
c.Write(b[i:i+1])
}

Related

How to convert uint8 slice to string

What's the best way to convert from []uint8 to string?
I'm using http://github.com/confluentinc/confluent-kafka-go/kafka
To read events from kafka. But it does not return plain string event.
It returns event with type []uint8.
How can I convert this event from []uint8 to string?
byte is an alias for uint8, which means that a slice of uint8) (aka []uint8) is also a slice of byte (aka []byte).
And byte slices and strings are directly convertible, due to the fact that strings are backed by byte slices:
myByteSlice := []byte{ ... } // same as myByteSlice := []uint8{ ... }
myString := string(myByteSlice) // myString is a string representation of the byte slice
myOtherSlice := []byte(myString) // Converted back to byte slice

encode object to bytes by golang unsafe?

func Encode(i interface{}) ([]byte, error) {
buffer := bytes.NewBuffer(make([]byte, 0, 1024))
// size := unsafe.Sizeof(i)
size := reflect.TypeOf(i).Size()
fmt.Println(size)
ptr := unsafe.Pointer(&i)
startAddr := uintptr(ptr)
endAddr := startAddr + size
for i := startAddr; i < endAddr; i++ {
bytePtr := unsafe.Pointer(i)
b := *(*byte)(bytePtr)
buffer.WriteByte(b)
}
return buffer.Bytes(), nil
}
func TestEncode(t *testing.T) {
test := Test{10, "hello world"}
b, _ := Encode(test)
ptr := unsafe.Pointer(&b)
newTest := *(*Test)(ptr)
fmt.Println(newTest.X)
}
I am learning how to use golang unsafe and wrote this function for encoding any object. I meet with two problems, first, dose unsafe.Sizeof(obj) always return obj's pointer size? Why it different from reflect.TypeOf(obj).Size()? Second, I want to iterate the underlying bytes of obj and convert it back to obj in TestEncode function by unsafe.Pointer(), but the object's values all corrupt, why?
First, unsafe.Sizeof returns the bytes that needs to store the type. It is a little bit tricky, but it does not mean bytes that needs to store the data.
For example, a slice, as it is well known, stores 3 4-byte ints on a 32bit machine. One uintptr for memory address of the underlying array, and two int32 for len and cap. So no matter how long a slice is or what type it is of, a slice takes always 12 bytes on a 32 bit machine. Likely, a string uses 8 bytes: 1 uintptr for address and 1 int32 for len.
As for difference between reflect.TypeOf().Size, it is about interface. reflect.TypeOf looks into the interface and gets an concrete type, and reports bytes needed about the concrete type, while unsafe.Sizeof just returns 8 for an interface type: 2 uintptr for a pointer to the data and a pointer to the method lists.
Second part is quite clear now. For one, unsafe.Pointer is taking the address of the interface, instead of the concrete type. Two, in TestEncode, unsafe.Pointer is taking address to the 12-byte slice "header". There might be other errors, but with the two mentioned, they are meaningless to spot.
Note: I avoid talking about orders of the uintptr and int32 not only because I don't know, but also becuase they are not documented, unsafe, and implentation depended.
Note 2: Conclusion: Don't try to dump memory of a Go data.
Note 3: I change everything to 32 bit becuase playground is using it, so it is easier to check.

How do I convert byte array to io. stream and convert it back to byte array?

func main(){
bytearray:=[]byte{"data"}
reader := bytes.NewReader(stdout.Bytes())
transfer(reader)
}
Function 2
func transfer(reader *Reader){
bytearray:= //How do I get the original byte array?
}
Basically I want to send byte array from one function to another using readers or writers
bytes.Buffer is what you need. It can convert a byte slice to an io.Reader/io.Writer:
buf := bytes.NewBuffer([]bytes{...})
And to read from an io.Reader into a byte slice:
s, err := ioutil.ReadAll(r)
Converting to/from byte arrays is left as a trivial exercise for the reader.

Putting int8 into byte array

I have the following byte array:
buf := make([]byte, 1)
var value int8
value = 45
buf[0] = value // cannot use type int8 as type []byte in assignment
And when I want to put a char value into the byte array I get the error that I cannot use type int8 as type []byte in assignment. What's wrong? How do I do this?
The issue you're having their is that although int8 and byte are roughly equivalent, they're not the same type. Go is a little stricter about this than, say, PHP (which isn't strict about much). You can get around this by explicitly casting the value to byte:
buf := make([]byte, 1)
var value int8
value = 45
buf[0] = byte(value) // cast int8 to byte
Try this:
buf := make([]byte, 1)
var value int8
value = 45
buf[0] = byte(value)
UPDATE: Took out the code converting negative numbers to positive ones. It appears that byte(...) already does this conversion in current versions of Go.

How can I convert from []byte to [16]byte?

I have this code:
func my_function(hash string) [16]byte {
b, _ := hex.DecodeString(hash)
return b // Compile error: fails since [16]byte != []byte
}
b will be of type []byte. I know that hash is of length 32. How can I make my code above work? Ie. can I somehow cast from a general-length byte array to a fixed-length byte array? I am not interested in allocating 16 new bytes and copying the data over.
There is no direct method to convert a slice to an array. You can however do a copy.
var ret [16]byte
copy(ret[:], b)
The standard library uses []byte and if you insist on using something else you will just have a lot more typing to do. I wrote a program using arrays for my md5 values and regretted it.

Resources