Hey there, I got a TCP socket read function that uses ReadBytes() function, I’m using 0x0A as delimiter but that’s not working because sometimes that 0x0A comes at the middle of the packet, what I really need is passing 0x0D 0x0A which means “\r\n”, but I found nothing like that. Below my code;
Hey Benjamin, I tried both both the 2 ones seems like they search for “\r” or “\n”, I really need searching for both at time, I searched here for a solution using scanner and found that one that works good;
// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
if len(data) > 0 && data[len(data)-1] == '\r' {
return data[0 : len(data)-1]
}
return data
}
func ScanCRLF(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.Index(data, []byte{'\r', '\n'}); i >= 0 {
// We have a full newline-terminated line.
return i + 2, dropCR(data[0:i]), nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), dropCR(data), nil
}
// Request more data.
return 0, nil, nil
}
And below the usage;
// Read client data from channel
func (c *Client) listen() {
reader := bufio.NewReader(c.conn)
scanner := bufio.NewScanner(reader)
scanner.Split(ScanCRLF)
for scanner.Scan() {
c.Server.onNewMessage(c, strings.ToUpper(hex.EncodeToString(scanner.Bytes())+"0d0a"))
}
}
You think is it a good practice in GO? The way I did…
Sure if that’s the functionality that you need, then you should use it
All that’s doing is creating a new SplitFunc for the scanner based on the ScanLines splitting function which is the default for a bufio.Scanner, so it should work well, since the only difference between ScanLines and ScanCRLF is this:
if i := bytes.IndexByte(data, '\n'); i >= 0 {
Becomes this:
if i := bytes.Index(data, []byte{'\r', '\n'}); i >= 0 {