Write a network client for TCP and UDP
Write a network server for TCP and UDP
Use goroutines to process requests
Load test a network server
Source Code
The source code for this chapter is available from the https://github.com/Apress/Software-Development-Go repository.
TCP Networking
In this section, you will explore creating TCP applications using the standard Go network library. The code that you will write is both TCP client and server.
TCP Client
Now that you understand how to write a TCP client, in the next section you will learn how to write a TCP server.
TCP Server
The code uses the Accept function of the Listener object, which is returned when calling the net.Listen(..) function. The Accept function waits until it receives a connection.
When the client is connected successfully, the code proceeds by calling the handleRequest function in a separate goroutine. Having requests processed in a separate goroutine allows the application to process requests concurrently.
The code reads the data sent by the client using the Read(..) function of the connection and writes the response back using the Write(..) function of the same connection.
Because the code uses a goroutine, the TCP server is able to process multiple client requests without any blocking issues.
UDP Networking
In this section, you will look at writing network applications using the UDP protocol.
UDP Client
In this section, you will write a simple UDP application that communicates with a quote-of-the-day(qotd) server that returns a string quote and prints it out to the console. The following link provides more information about the qotd protocol and the available public servers: www.gkbrk.com/wiki/qotd_protocol/. The sample code connects to the server djxms.net that listens on port 17.
“Man can climb to the highest summits, but he cannot dwell there long.”
George Bernard Shaw (1856-1950)
The library does a lookup to ensure that the provided domain is valid, and this is done by doing a DNS lookup. On encountering error, it will return a non-nil for the err variable.
In this section, you learned how to connect a UDP server using the standard library. In the next section, you will learn more on how to write a UDP server.
UDP Server
The code uses the ReadFromUDP(..) function of the UDP connection to read the data that is sent by the client to print it out to the console.
Concurrent Servers
In the previous section, you wrote a UDP server but one of the things that is lacking is its ability to process multiple UDP client requests. Writing a UDP server that can process multiple requests is different from normal TCP. The way to structure the application is to spin off multiple goroutines to listen on the same connection and let each goroutine take care of processing the request. The code can be found inside the udp/concurrent directory. Let’s take a look at what it is doing differently compared to the previous UDP server implementation.
Now that the listen function is run as several goroutines, it waits on an incoming UDP request by calling the ReadFromUDP function. When an incoming UDP request is detected, one of the running goroutines processes it.
Load Testing
In this section, you will look at using load testing to test the network server that you wrote in the previous sections. You will be using an open source load testing tool called fortio. which can be downloaded from https://github.com/fortio/fortio; for this book, use version v1.21.1.
Using the load testing tool, you will see the timing difference between code that is designed to handle requests without using goroutines vs. code that is designed to handle requests using goroutines. For this exercise, you will use the UDP server that is inside the chapter9/udp/loadtesting directory. You will compare between the UDP server that uses goroutines inside the chapter9/udp/loadtesting/concurrent directory and the UDP server that does not use goroutines inside chapter9/udp/loadtesting/server.
The average time recorded this time is 26.354ms, which is more than the previous result of 11.426. With this, you can conclude that it is important to remember to use goroutines when writing a network server application to ensure concurrent request processing.
Summary
In this chapter, you learned how to create network applications using TCP and UDP. You learned how to write client and server for both protocols. You learned how to write an application that can process multiple requests concurrently using goroutines.
This is an important step to understand because it is the foundation of how to write network applications that can process huge amounts of traffic. This chapter is a stepping-stone for the upcoming chapter where you will look at different styles of writing network applications in Linux.