[Golang] Reading from net.Conn hangs or breaks early

Hi. I’m kinda new to Go and stuck with an issue of hanging net connection or not reading full message from net connection.
Here’s an example how I do it:

const connChunkSize int = 1024

func readConnectionMessage(conn net.Conn) string {
	buffer := bytes.NewBuffer(nil)
	for {
		chunk := make([]byte, connChunkSize)
		read, err := conn.Read(chunk)

		if read > 0 {
			buffer.Write(chunk[:read])
		}

		if read == 0 || errors.Is(err, io.EOF) {
			break
		} else if err != nil {
			return err.Error()
		}
	}

	return buffer.String()
}

I receive a “$1\n$4\nPING” on the first loop and on the second loop conn.Read will hang.
If I do break if statement when read bytes are < 1024 like:

if read < 1024 || errors.Is(err, io.EOF) {
    break
}

This will work for the first test case. But on the second test case, which’s doing this command in terminal echo -e "PING\nPING" | redis-cli, it’ll read only the first PING command as in the first test case, functionality will respond to 1 command and close the connection.

So the question is, how to properly read all the data from connection and avoid hanging? I’ve tried different ways of implementing reading from connection, but all have the same result.

Sorry for the delayed response.

The issue actually happens outside readConnectionMessage. Your code was already nearly perfect. But why did it hang? @vyivrain

Because the code didn’t try to read the second ping after sending back the first pong.

To continue reading pings, wrap a for loop around the read-eval-write logic:

func handleConnection(conn net.Conn) {
    defer conn.Close()
    for {
        read
        eval
        write
    }
}

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.