Skip to content

Instantly share code, notes, and snippets.

@MilosSimic
Last active September 22, 2022 11:00
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save MilosSimic/ae7fe8d70866e89dbd6e84d86dc8d8d5 to your computer and use it in GitHub Desktop.
Save MilosSimic/ae7fe8d70866e89dbd6e84d86dc8d8d5 to your computer and use it in GitHub Desktop.
tcp server/client in golang using binary data
package main
import (
"bytes"
"encoding/gob"
"fmt"
"net"
// "time"
)
type Message struct {
ID string
Data string
}
func send(conn net.Conn) {
// lets create the message we want to send accross
msg := Message{ID: "Yo", Data: "Hello"}
bin_buf := new(bytes.Buffer)
// create a encoder object
gobobj := gob.NewEncoder(bin_buf)
// encode buffer and marshal it into a gob object
gobobj.Encode(msg)
conn.Write(bin_buf.Bytes())
}
func recv(conn net.Conn) {
// create a temp buffer
tmp := make([]byte, 500)
conn.Read(tmp)
// convert bytes into Buffer (which implements io.Reader/io.Writer)
tmpbuff := bytes.NewBuffer(tmp)
tmpstruct := new(Message)
// creates a decoder object
gobobjdec := gob.NewDecoder(tmpbuff)
// decodes buffer and unmarshals it into a Message struct
gobobjdec.Decode(tmpstruct)
fmt.Println(tmpstruct)
}
func main() {
conn, _ := net.Dial("tcp", ":8081")
// Uncomment to test timeout
// time.Sleep(5 * time.Second)
// return
send(conn)
recv(conn)
}
package main
import (
"bytes"
"encoding/gob"
"fmt"
"io"
"log"
"net"
"time"
)
// Create your custom data struct
type Message struct {
ID string
Data string
}
func logerr(err error) bool {
if err != nil {
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
log.Println("read timeout:", err)
} else if err == io.EOF {
} else {
log.Println("read error:", err)
}
return true
}
return false
}
func read(conn net.Conn) {
// create a temp buffer
tmp := make([]byte, 500)
// loop through the connection to read incoming connections. If you're doing by
// directional, you might want to make this into a seperate go routine
for {
_, err := conn.Read(tmp)
if logerr(err) {
break
}
// convert bytes into Buffer (which implements io.Reader/io.Writer)
tmpbuff := bytes.NewBuffer(tmp)
tmpstruct := new(Message)
// creates a decoder object
gobobj := gob.NewDecoder(tmpbuff)
// decodes buffer and unmarshals it into a Message struct
gobobj.Decode(tmpstruct)
// lets print out!
fmt.Println(tmpstruct)
return
}
}
func resp(conn net.Conn) {
msg := Message{ID: "Yo", Data: "Hello back"}
bin_buf := new(bytes.Buffer)
// create a encoder object
gobobje := gob.NewEncoder(bin_buf)
// encode buffer and marshal it into a gob object
gobobje.Encode(msg)
conn.Write(bin_buf.Bytes())
conn.Close()
}
func handle(conn net.Conn) {
timeoutDuration := 2 * time.Second
fmt.Println("Launching server...")
conn.SetReadDeadline(time.Now().Add(timeoutDuration))
remoteAddr := conn.RemoteAddr().String()
fmt.Println("Client connected from " + remoteAddr)
read(conn)
resp(conn)
}
func main() {
server, _ := net.Listen("tcp", ":8081")
for {
conn, err := server.Accept()
if err != nil {
log.Println("Connection error: ", err)
return
}
go handle(conn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment