# Networking

How do client and server communicate? They need agreed-upon rules for packaging, transmitting and interpreting information sent over a physical network.

Network protocols are a set of rules outlining how connected devices communicate across a network. Protocols include:

  1. Communication protocols, for transferring data. These include HTTP for web traffic, FTP for sending files over a network, or TCP/IP for data packets.
  2. Security protocols are meant for establishing secure channels for the safe transmission of data. These include SFTP and SSH.
  3. Network management prototols are meant for controlling and managing devices on a network. These include SMNP and ICMP.

# TCP/IP

TCP/IP stands for Transmission Control Protocol/Internet Protocol and is a suite of communication protocols used to interconnect network devices on the internet. TCP/IP is also used as a communications protocol in a private computer network. TCP/IP actually refers to two protocols that work together: Transmission Control Protocol (TCP) and Internet Protocol (IP).

TCP defines how applications can create channels of communication across a network. It also manages how a message is assembled into smaller packets before they are then transmitted over the internet and reassembled in the right order at the destination address.

IP defines how to address and route each packet to make sure it reaches the right destination. Each gateway computer on the network checks this IP address to determine where to forward the message.

# How does TCP/IP work?

TCP/IP uses the client-server model of communication in which a user or machine (a client) is provided a service, like sending a webpage, by another computer (a server) in the network.

Every device on a network requires a unique identifier, also known as an Internet Protocol address or IP address. This is usually presented as a numerical label such as 192.0.2.1 (four digits from 0-255, dot separated).

Network addresses also include a port, which is an integer label assigned to a specific network channel on that receiving device. For example, port 80 is normally used when requesting web pages; port 21 is commonly used to send files using FTP.

IP address dialog on macOS, showing IP address of my machine, and the network router connecting to the internet
IP address dialog on macOS, showing IP address of my machine, and the network router connecting to the internet

A client connecting to a remote server needs to:

  1. Create a network connection to the specific IP address and port of the server,
  2. Send data to that address and port.
  3. Handle any errors that arise.
  4. Close the connection on completion.

Note that we commonly combine prototols. For example, a web browser connecting to a remote web server will make HTTP requests over a TCP/IP networking to port 80. We'll use this in the next section when we discuss HTTP.

# Networking in practice

Networking is a complex topic, but it's essential for building modern applications. Here are some common networking tasks you might encounter:

  1. Sending data between devices. This is the most basic networking task, and it's essential for building any kind of networked application.
  2. Handling errors. Networks are unreliable, so you need to be prepared for errors like dropped packets, slow connections, or network outages.
  3. Security. Networks are vulnerable to attacks, so you need to secure your applications against threats like
  4. Scaling. As your application grows, you'll need to scale your network to handle more traffic and more users. This can involve load balancing, caching, and other techniques to improve performance.
  5. Monitoring. You need to monitor your network to detect problems and optimize performance. This can involve tools like Wireshark or Nagios.
  6. Optimizing performance. Networks can be slow, so you need to optimize your applications to minimize latency and maximize throughput. This can involve techniques like caching or compression.
  7. Debugging. When things go wrong, you need to be able to debug your network to find the problem. This can involve tools like ping or traceroute.

# Creating network connections

There are multiple ways to create network connections. The most common are:

  1. Synchronous connections are blocking, meaning the client waits for the server to respond before continuing. This is the simplest way to create a connection, but it can be slow if the server is far away or slow to respond.
  2. Asynchronous connections are non-blocking, meaning the client can continue to do other things while waiting for the server to respond. This is more complex to implement, but can be faster and more efficient.
  3. Long polling is a technique where the client sends a request to the server and waits for a response. If the server has no new data, it waits a while before responding. This is useful for real-time applications like chat or notifications.

Kotlin is able to handle all of these connection types, but you'll need to use different libraries and techniques depending on the type of connection you want to create.

Kotlin has built-in support for networkin using java.net classes:

import java.net.ServerSocket
import java.net.Socket

fun client() {
    val client = Socket("127.0.0.1", 9999)
    val output = PrintWriter(client.getOutputStream(), true)
    val input = BufferedReader(InputStreamReader(client.inputStream))

    println("Client sending [Hello]")
    output.println("Hello")
    println("Client receiving [${input.readLine()}]")
    client.close()
}

You can also use third-party libraries like OkHttp or Retrofit to make networking easier. Here's a similar example using Ktor, the official networking library maintained by JetBrains:

import io.ktor.client.HttpClient

suspend fun main() {
    val client = HttpClient()
    val response = client.get<String>("http://ktor.io")
    println("Response: $response")
}

Full details are in the Ktor client documentation.