You can use two distinct algorithms to handle end of messages
1: The first bytes of the message (maybe an int32) mark the size of the message, so the server knows when the message ends. This approach requires the client to know "a priore" the size of the message befor starting to send it.
2: The first bytes of the message is a mark (maybe an GUID) and after all the bytes are trasnfered your client sends the mark, so when the server sees the mark it knows that the message has ended. This approach requires you to make an escape scheme so when the client tries to write the mark in the middle of the message it will escape it with some byte sequence (more or less like you do when you want to print "\n", you write "\\n").
But, if both client and server are Go programs, you can use NetChannel which handle everything for you.