Skip to content

Instantly share code, notes, and snippets.

@raszia
Last active March 9, 2023 07:33
Show Gist options
  • Save raszia/4ef9f386b6e370a94574819c5b0def64 to your computer and use it in GitHub Desktop.
Save raszia/4ef9f386b6e370a94574819c5b0def64 to your computer and use it in GitHub Desktop.
Here is an example of how you could implement a TCP server and client in Go that handles incoming messages with a fixed-length header:
package main
import (
"encoding/binary"
"fmt"
"net"
)
const (
headerSize = 4 // the size of the message header, in bytes
protocolTCP = "tcp"
serverAddr = "localhost:8585"
)
func main() {
// Connect to server
conn, err := net.Dial(protocolTCP, serverAddr)
if err != nil {
panic(err)
}
defer conn.Close()
var message []byte
//create 4KB message
for i := 0; i < 4096; i++ {
message = append(message, []byte("a")...)
}
header := make([]byte, headerSize)
//encodes a uint32 value as a big-endian byte sequence and stores it in a byte slice.
binary.BigEndian.PutUint32(header, uint32(len(message)))
//create the data with header and body
data := append(header, message...)
// Send message
conn.Write(data)
// Read response
responseHeader := make([]byte, headerSize)
_, err = conn.Read(responseHeader)
if err != nil {
fmt.Println("Error reading response header:", err)
return
}
responseLength := binary.BigEndian.Uint32(responseHeader)
response := make([]byte, responseLength)
_, err = conn.Read(response)
if err != nil {
panic(err)
}
fmt.Println("Response len:", len(response))
}
package main
import (
"encoding/binary"
"fmt"
"net"
)
const (
headerSize = 4 // the size of the message header, in bytes
protocolTCP = "tcp"
addr = ":8585"
)
func main() {
ln, err := net.Listen(protocolTCP, addr)
if err != nil {
panic(err)
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
fmt.Println(err)
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
for {
// Read the message header to determine the message length
header := make([]byte, headerSize)
_, err := conn.Read(header)
if err != nil {
fmt.Println(err)
return
}
messageSize := binary.BigEndian.Uint32(header)
// Read the message payload
message := make([]byte, messageSize)
_, err = conn.Read(message)
if err != nil {
fmt.Println(err)
return
}
// Process the message
fmt.Println("Received message len:", len(message))
var messageRes []byte
//create 4KB message for response
for i := 0; i < 4096; i++ {
messageRes = append(messageRes, []byte("a")...)
}
//encodes a uint32 value as a big-endian byte sequence and stores it in a byte slice.
binary.BigEndian.PutUint32(header, uint32(len(messageRes)))
//create the data with header and body to response
data := append(header, messageRes...)
// Send response message
conn.Write(data)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment