In this tutorial, we will learn about “How to create TCP client and server using Golang using step by step guide”. The client-server architecture basically provides a flexible and scalable model for building distributed systems where clients and servers collaborate to achieve various tasks and provide services to end-users. It’s a foundational concept in modern computing, powering a wide range of applications and services on the internet and enterprise networks. We will learn more about client-server architecture and implement the same in Golang. So, let us begin the tutorial.
What is Client-Server Architecture
Client-server architecture is a computing model where tasks or workloads are divided between service requesters (clients) and service providers (servers). It’s a fundamental model in networked systems where clients initiate requests for resources or services, and servers respond to those requests by providing the requested resources or services.
Here are the key components and characteristics of client-server architecture:
- Clients: Clients are devices or software applications that request services or resources from servers. Clients initiate communication by sending requests to servers. Examples of clients include web browsers, mobile apps, desktop applications, etc.
- Servers: Servers are devices or software applications that provide services or resources to clients. Servers listen for incoming requests from clients, process those requests, and send back responses. Examples of servers include web servers, database servers, email servers, etc.
- Communication: Communication between clients and servers typically occurs over a network using various communication protocols such as HTTP, HTTPS, TCP/IP, etc. Clients send requests to servers, and servers respond to those requests with the requested data or services.
- Request-Response Model: Client-server architecture follows a request-response model, where clients send requests to servers, and servers respond to those requests with the requested data or services. This model allows for efficient distribution of workloads and resources.
- Scalability: Client-server architecture allows for scalable systems where multiple clients can communicate with multiple servers simultaneously. This scalability enables systems to handle increasing workloads by distributing tasks across multiple servers.
- Centralized Services: Servers in client-server architecture often provide centralized services, such as databases, file storage, authentication, etc. Clients access these centralized services by sending requests to the appropriate servers.
- Decoupling of Presentation and Data Processing: In many client-server applications, the presentation layer (client-side) is decoupled from the data processing layer (server-side). This separation of concerns allows for better maintainability, scalability, and flexibility in software development.
How to Create TCP Client and Server Using Golang [Step by Step Guide]
Also Read: How to Implement Stack in Golang [Step by Step Guide]
In Go, you can create TCP client and server applications using the “net “ package, which provides support for various networking protocols, including TCP. There are different packages available to create TCP Client and Server in Golang. These are mentioned below.
- Using
net.Listen
andnet.Dial
: This is the simplest way to create a TCP server and client. The server listens for incoming connections usingnet.Listen
, and the client connects to the server usingnet.Dial
. - Using
net.TCPListener
andnet.TCPConn
: You can also create TCP servers and clients usingnet.TCPListener
andnet.TCPConn
types, which provide more control over TCP-specific options and behaviors. - Using Libraries: There are also third-party libraries and frameworks available in Go for building TCP servers and clients, such as
github.com/golang/net
,github.com/hashicorp/yamux
, etc. These libraries may offer additional features and functionalities beyond the standardnet
package.
For the sake of this tutorial, we will use “net” package to write the client-server code. In our example, we have created a client which will send array of strings to the server. Our server in return will reverse these strings and return back the output to the client.
Below, I have provided the code of both a TCP server and a TCP client. The examples provided below demonstrate the first method using the standard net
package. Depending on your requirements and use case, you can choose the approach that best fits your needs.
Prerequisites
- Go software installed
- VS Code IDE (or any other Go IDE)
- Basic understanding on Go
Create TCP Client File (tcpClient.go)
This Go code defines a function SendAndReceiveMessages
responsible for sending messages to a server and printing the reversed response. this function facilitates communication between a client and a server over TCP, sending messages and printing the reversed responses. Create a new file and save below code. I have saved it in tcpClient.go file.
/* This file will handle the client-side logic, sending messages to the server*/ package main import ( "bufio" "fmt" "net" ) // Sends each message from the array to the server and prints the reversed response func SendAndReceiveMessages(messages []string, port string) { for _, message := range messages { conn, err := net.Dial("tcp", "localhost:"+port) if err != nil { fmt.Println("Error connecting to the server: ", err) return } //Send message to the server conn.Write([]byte(message + "\n")) //Receive and print the response from the server response, err := bufio.NewReader(conn).ReadString('\n') if err != nil { fmt.Println("Error reading the response: ", err) return } fmt.Printf("Original: %s, Reversed: %s", message, response) defer conn.Close() } }
Create TCP Server File (tcpServer.go)
package main import ( "bufio" "fmt" "net" ) func handleClient(conn net.Conn) { defer conn.Close() scanner := bufio.NewScanner(conn) for scanner.Scan() { //Reverse the received message message := scanner.Text() reversedMessage := reverseString(message) //Send the reversed string back to the client conn.Write([]byte(reversedMessage + "\n")) } } func reverseString(message string) string { runes := []rune(message) for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { runes[i], runes[j] = runes[j], runes[i] } return string(runes) } func StartServer(port string) { listener, err := net.Listen("tcp", "localhost:"+port) if err != nil { fmt.Println("Error starting the server: ", err) return } defer listener.Close() fmt.Println("Server started. Listening on Port: ", port) for { conn, err := listener.Accept() if err != nil { fmt.Println("Error accepting the connection: ", err) continue } go handleClient(conn) } }
Create main.go File (main.go)
/* This file contains the main function and orchestrate the client and server logic */ package main import ( "time" ) func main() { //Start the server in a goroutine go StartServer("4040") //Wait fot sometime to ensure server has started <-time.After(time.Second * 2) message := []string{"Linux", "Nasa"} SendAndReceiveMessages(message, "4040") }
Create go.mod File
Next, create a mod file for the current project using the command go mod init <path>
as shown below.
[email protected]/client-server$ go mod init clientServer
Execute the Code
go build <go-file-path>
. In our case, the go file path is the current directory so we will use "."
to denote the command to pick all the .go files from current folder.[email protected]/client-server$ go build .
[email protected]/client-server$ .\clientServer.exe Server started. Listening on Port: 4040 Original: Linux, Reversed: xuniL Original: Nasa, Reversed: asaN
Summary
This step-by-step guide provides a comprehensive overview of creating TCP client and server applications using the Go programming language. From establishing connections to handling data exchange, readers will learn the fundamentals of TCP communication in Go, empowering them to build robust and efficient networked applications.