Whenever you have to build high performance oriented systems then writing a TCP server is always the best choice over an HTTP server, as TCP sockets are less hefty than HTTP. Go supports and provides a convenient way of writing TCP servers using a net package, which we will be covering in this recipe.
Creating a simple TCP server
How to do it...
In this recipe, we are going to create a simple TCP server that will accept a connection on localhost:8080. Perform the following steps:
- Create tcp-server.go and copy the following content:
package main
import
(
"log"
"net"
)
const
(
CONN_HOST = "localhost"
CONN_PORT = "8080"
CONN_TYPE = "tcp"
)
func main()
{
listener, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
if err != nil
{
log.Fatal("Error starting tcp server : ", err)
}
defer listener.Close()
log.Println("Listening on " + CONN_HOST + ":" + CONN_PORT)
for
{
conn, err := listener.Accept()
if err != nil
{
log.Fatal("Error accepting: ", err.Error())
}
log.Println(conn)
}
}
- Run the program with the following command:
$ go run tcp-server.go
How it works...
Once we run the program, the TCP server will start locally listening on port 8080.
Let’s understand what each line in the program means:
- package main: This defines the package name of the program.
- import ( "log" "net"): This is a preprocessor command that tells the Go compiler to include all files from the log and net package.
- const ( CONN_HOST = "localhost" CONN_PORT = "8080" CONN_TYPE = "tcp" ): We declare constants in a Go program using the const keyword. Here, we declare three constants—one is CONN_HOST with a value of localhost, another one is CONN_PORT with a value as 8080, and lastly CONN_TYPE with a value as tcp.
Next, we declared the main() method from where the program execution begins. As this method does a lot of things, let’s understand it line by line:
- listener, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT): This creates a TCP server running on localhost at port 8080.
- if err != nil { log.Fatal("Error starting tcp server: ", err) }: Here, we check if there is any problem in starting the TCP server. If there is, then log the error and exit with a status code of 1.
- defer listener.Close(): This defer statement closes a TCP socket listener when the application closes.
Next, we accept the incoming request to the TCP server in a constant loop, and if there are any errors in accepting the request, then we log it and exit; otherwise, we simply print the connection object on the server console, as follows:
for
{
conn, err := listener.Accept()
if err != nil
{
log.Fatal("Error accepting: ", err.Error())
}
log.Println(conn)
}