This is how the data comes in
[2 68 52 50 58 49 48 32]
[32 48 32 32 48 32 32 48]
[48 49 48 49 48 32 32 32]
[32 3 120]
[2 68 52 50 58 49 49 32]
[32 48 32 32 48 32 32 48]
[48 49 48 49 48 32 32 32]
[32 3 121]
[2 68 52 50 58 49 50 32]
[32 48 32 32 48 32 32 48]
[48 49 48 49 48 32 32 32]
[32 3 122]
[2 68 52 50 58 49 51 32]
[32 48 32 32 48 32 32 48]
[48 49 48 49 48 32 32 32]
[32 3 123]
[2 68 52 50 58 49 52 32]
[32 48 32 32 48 32 32 48]
[48 49 48 48 48 32 32 32]
[32 3 125]
[2 68 52 50 58 49 52 32]
[32 48 32 32 48 32 32 48]
[48 49 51 48 48 32 32 32]
[32 3 126 2 68 52 50 58 49 52 32 32 48 32 32 48]
[32 32 48 48 49 51 48 48]
[32 32 32 32 3 126]
[2 68 52 50 58 49 52 32]
[32 48 32 32 48 32 32 48]
[48 49 51 48 48 32 32 32]
[32 3 126]
[2 68 52 50 58 49 52 32]
[32 48 32 32 48 32 32 48]
[48 49 48 49 48 32 32 32]
[32 3 124 2 68 52 50 58 49 52 32 32 48 32 32 48]
[32 32 48 48 49 48 49 48]
[32 32 32 32 3 124]
[2 68 52 50 58 49 53 32]
[32 48 32 32 48 32 32 48]
[48 49 48 49 48 32 32 32]
[32 3 125]
This is how I demonstrated this
conn, err := net.Dial("tcp", "192.168.2.64:9001")
if err != nil {
fmt.Println("Connection not established")
}
fmt.Println(conn.LocalAddr())
for {
buffer := make([]byte, 1024)
bytesRead, err := conn.Read(buffer)
if err != nil {
fmt.Println(err)
}
fmt.Println(buffer[:bytesRead])
}
This is the program I’m using to try and parse it.
package main
import (
"bufio"
"fmt"
"io"
"net"
)
func calculateXORChecksum(data []byte) byte {
var checksum byte
for _, b := range data {
checksum ^= b
}
return checksum
}
func findByte(data []byte) int {
for index, aByte := range data {
if aByte == 2 {
return index
}
}
return -1
}
func readSTXETXWithChecksum(conn net.Conn) ([]byte, byte, error) {
reader := bufio.NewReader(conn)
// Read until we get the ETX (ASCII 3) character
message, err := reader.ReadBytes(3)
if err != nil {
return []byte(""), 0, err
}
checksumByte, err := reader.ReadByte()
if err != nil {
return []byte(""), 0, err
}
data := append(message, checksumByte) // All characters including the checksum
return data, checksumByte, nil
}
func main() {
conn, err := net.Dial("tcp", "192.168.2.64:9001")
if err != nil {
fmt.Println("Connection not established")
}
fmt.Println(conn.LocalAddr())
for {
fmt.Println()
data, _, err := readSTXETXWithChecksum(conn)
if err == io.EOF {
fmt.Println("Connection closed by the peer")
} else if err != nil {
fmt.Println("Error reading message:", err)
} else {
fmt.Println("Received data:", []byte(data))
fmt.Println("Received data:", string([]byte(data)[:len(data)-1]))
fmt.Println()
}
}
}
The problem is when I get bytes array such as [32 3 126 2 68 52 50 58 49 52 32 32 48 32 32 48]
anything after 3
and checksum byte
gets discarded. This is due to the fact that in each itteration of the for loop a new scanner is declared. However if I declare a reader outside the for loop the buffer array is gonna get filled up at some point and there may be missing data as a new one is declared when it is full.
I feel quite stupid for not being able to solve something that seems simple.
I tried something manual but cant get it right and feel like it is not the right approach
buffer := make([]byte, 1024)
var aLine []byte
var remaining []byte
for {
numberRead, err := conn.Read(buffer)
if err != nil {
fmt.Println("the error")
}
if len(remaining) != 0 {
aLine = append(remaining, buffer[:numberRead]...)
}
// fmt.Println(aLine)
foundEnd := findByte(buffer[:numberRead])
if foundEnd != -1 {
aLine = append(aLine, buffer[:foundEnd+1]...)
fmt.Println(aLine)
aLine = nil
if numberRead > foundEnd+1 {
leftover := buffer[foundEnd+1 : numberRead]
remaining = append(remaining, leftover...)
}
} else {
aLine = append(aLine, buffer[:numberRead]...)
}