TCP Client in Golang
Published: 2022-12-30 09:09:33

This article is an extension of previous article in which we saw how to create a TCP server in golang which can communicate with concurrent users. In this article we are going to see how to make a TCP client in golang that sends the request to the server and consumes the response received back, it is similar to client and server terminal chat where until the client doesn’t quit the communication is taking place. We will be using the net package from the standard library, which is a set of core packages that enhance and extend the language. We don’t need to build our own package or download any from a third party.

For using the net package use the import statement to import the package.

`import "net" `

We will define some variables which will be required to make a tcp connection, and as the variables are not going to change in the future so we will declare them as constants.

`const (
   HOST = "localhost"
   PORT = "8080"
   TYPE = "tcp"
)`

The above declared constants are HOST which will be localhost in this case, the PORT number where we can access the server here it is 8080 and the TYPE of network that will be used here it will be tcp.

We will create a util function named checkErr where we pass the error and a error message string as an argument and it handles the error.

`func checkErr(err error, msg string) {
   if err != nil {
       fmt.Println("error: ", msg, " ", err)
       os.Exit(1)
   }
}`

For connecting with the desired server we use the Dial function from the net package which takes two arguments the first being the network type and the second being the address. Dial function returns net.Conn and the error, we handle the error in the separate checkErr function. We use the defer keyword to close the connection when the program is terminated.

`conn, err := net.Dial(TYPE, HOST+":"+PORT)
defer conn.Close()
checkErr(err, "Unable to connect")`

After connecting with the server we read the response from the server using the Read function which takes a slice of byte as argument where it stores the data.

`buf := make([]byte, 1024)
_, err = conn.Read(buf)
checkErr(err, "Error reading data")
fmt.Println(string(buf))`

For sending messages to the server we first take the input message from the terminal using the functions from the bufio package. We first create a Reader and then read the data from the terminal using the ReadString function.

`msgReader := bufio.NewReader(os.Stdin)
fmt.Print("Enter your text: ")
msg, _ := msgReader.ReadString('\n')`

After getting the message we use the Write function to send the message to the server.

`conn.Write([]byte(msg))`

Here is the full code for the same.

`
package main

import (
   "bufio"
   "fmt"
   "net"
   "os"
)

const (
   HOST = "localhost"
   PORT = "8080"
   TYPE = "tcp"
)

func main() {
   fmt.Println("!! TCP Client in golang !!")

   conn, err := net.Dial(TYPE, HOST+":"+PORT)
   defer conn.Close()
   checkErr(err, "Unable to connect")

   buf := make([]byte, 1024)
   _, err = conn.Read(buf)
   checkErr(err, "Error reading data")
   fmt.Println(string(buf))

   for {
       msgReader := bufio.NewReader(os.Stdin)
       fmt.Print("Enter your text: ")
       msg, _ := msgReader.ReadString('\n')
       conn.Write([]byte(msg))
   }
}

func checkErr(err error, msg string) {
   if err != nil {
       fmt.Println("error: ", msg, " ", err)
       os.Exit(1)
   }
}
`