Building a TCP Server and Client in Go
In this post, we'll delve into creating a simple TCP server and client in Go. We'll explore the server and client code in parts, breaking down the functionality of each component. This tutorial is aimed at programmers who want to understand how to use Go's net package for network communication.
TCP Server Code
Let's start with the TCP server. The server listens for incoming connections, reads data sent by clients, and prints the received messages to the console.
1. Importing Necessary Packages
We import three packages: fmt
for formatted I/O, io
for input/output operations, and net
for network-related functions.
2. Setting Up the Listener
Here, we set up a TCP listener on port 8088. If an error occurs during this process, we handle it with panic(err)
, which stops the program and prints the error. We also ensure that the listener is closed when the program exits using defer connection.Close()
.
3. Accepting Client Connections
We enter an infinite loop to accept incoming client connections. The Accept()
method waits for and returns the next connection to the listener. Each connection is handled in a separate goroutine, allowing the server to handle multiple clients concurrently.
4. Handling Client Connections
The handleClient
function reads data from the client in a loop. If the client disconnects (beof
is true), the function prints a message and exits the loop. Otherwise, it prints the received message.
5. Reading Data from the Client
The readBuffer
function reads data into a buffer b
of size 1024 bytes
. If an error occurs during reading, it checks if the error is io.EOF
, indicating the end of the file (client disconnected). If so, it returns true for beof
. For other errors, it panics. If the read is successful, it returns the read bytes and false for beof
.
TCP Client Code
Next, let's look at the TCP client. The client connects to the server, reads user input from the console, and sends it to the server.
1. Importing Necessary Packages
We import the bufio
package for buffered I/O, fmt
for formatted I/O, net for network functions, os
for OS-level functions, and strings
for string manipulation.
2. Establishing a Connection to the Server
We establish a TCP connection to the server on port 8088 using net.Dial()
. If an error occurs, we handle it with panic(err)
.
3. Reading User Input and Sending Data to the Server
We enter an infinite loop where we read user input from the console using bufio.NewReader(os.Stdin).ReadString('\n')
. If an error occurs, we print the error and exit. We then trim any trailing whitespace from the input and send it to the server using conn.Write([]byte(input))
.
Full Code
server.go
client.go
Conclusion
In this post, we've walked through creating a simple TCP server and client in Go. We covered setting up the server to listen for connections, handling multiple clients concurrently, reading data from clients, and establishing a client connection to send data to the server. This foundational knowledge can be extended to build more complex networked applications in Go.
Feel free to experiment with the code, and happy coding!