Creating a simple TCP server in Go
package main
import (
"fmt"
"net"
"os"
)
const (
CONN_HOST = "localhost"
CONN_PORT = "3333"
CONN_TYPE = "tcp"
)
func main() {
// Listen for incoming connections.
l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
// Close the listener when the application closes.
defer l.Close()
fmt.Println("Listening on " + CONN_HOST + ":" + CONN_PORT)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
// Handle connections in a new goroutine.
go handleRequest(conn)
}
}
// Handles incoming requests.
func handleRequest(conn net.Conn) {
// Make a buffer to hold incoming data.
buf := make([]byte, 1024)
// Read the incoming connection into the buffer.
reqLen, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err.Error())
}
// Send a response back to person contacting us.
conn.Write([]byte("Message received."))
// Close the connection when you're done with it.
conn.Close()
}
If you build this and run it, you'll have a simple TCP server running on port 3333.
To test your server, send some raw data to that port:
echo -n "test out the server" | nc localhost 3333
You should get a response:
"Message received."
Written by Daniel Pepin
Related protips
7 Responses
I just wrote an article that describes how to "dockerize" a Go app very similar on the one you described here. Obviously I mentioned this post. Let me know if you like it: http://loige.com/simple-echo-server-written-in-go-dockerized
Just a little bug:
$ go run tcp_server.go
command-line-arguments
.\tcp_server.go:42: reqLen declared and not used
Regards!
Change unused variables with underscore ( _ ). Compiler won't complain.
Hi sir. would you please help me with this problem?
Hello Daniel!
I do not think it is good practice to require the handler to close the connection. It should be closed by the caller.
And I just realise, the use of ALL_UPPER_CASE_CONSTANTS
is not idiomatic go. Constants in go are named just as everything in go using camelcase, where the first letters case indicates wether the constant is exported or not from the package. Exporting from main
does not make sense, since you can not import a package named main
.
Can you update your example to set CONN_HOST to "". This way another computer can make a connection without too much hassle