Администрирование Linux

Теория: TCP/IP

Практически все взаимодействия в веб-приложениях – являются сетевыми. Запросы к сайтам из браузера, взаимодействие с базами данных, между Docker-контейнерами, системами кеширования, API внешних сервисов – всё это сводится к сетевым запросам. Сети крайне важны и для инфраструктурных задач. Начиная с ssh подключений к машинам, заканчивая организацией сетевого взаимодействия между сервисами внутри кластера или даже датацентрами.

Знание сетей можно грубо разделить на два уровня – инфраструктурный и прикладной. Первый – это всё что касается проводов, устройств и технологий (wi-fi, соты). На данном уровне работают сетевые инженеры и это слишком далеко от прикладной разработки. Второй уровень работает поверх инфраструктуры и не завязан на неё. Здесь мы оперируем программами на разных компьютерах, которые общаются друг с другом, не задумываясь (почти) о том, как физически данные ходят между ними.

Типичная ситуация – обращение к сайту. Здесь мы со своего компьютера отправляем запрос на другой компьютер и в ответ получаем страницу, которую показывает браузер. И хотя, судя по адресной строке, запрос выполняется по протоколу HTTP, всё чуть сложнее. HTTP – протокол прикладного уровня, он не знает про существование компьютеров в сети и работает уже поверх установленного соединения между компьютерами. А вот соединение делается с помощью протокола TCP, который нас интересует больше всего. На TCP держится практически всё сетевое взаимодействие.

TCP/IP

Протокол TCP позволяет общаться между собой процессам расположенным как на одном компьютере, так и на разных. Процессам, а не компьютерам, что очень важно. Подключение по TCP идёт из конкретного процесса в конкретный процесс. Для соединения нужно два параметра: ip–адрес и порт. Ip-адрес обычно устанавливается автоматически, а вот порт выбирается самим разработчиком, хотя и он может присваиваться автоматически. Связка адреса и порта однозначно говорит нам о том, с какой программой происходит связь. Именно поэтому параметра два. Одного ip-адреса недостаточно, тогда мы не сможем понять, какая программа хочет работать по сети.

TCP клиент-серверный протокол. То есть один компьютер выступает в качестве сервера, а те, кто к нему присоединяются – клиенты. Сервер во время старта указывает ip-адрес и порт, на которых нужно запуститься. Говорят, что сервер "слушает" порт.

// Пример на JS

// СЕРВЕР

import net from 'net'

// Этот сервер отвечает Echo Server на каждый входящий запрос
const server = net.createServer((socket) => {
  socket.write('Echo server\r\n')
  socket.pipe(socket)
})

// Запускаем сервер на 3000 порту
// ip-адрес должен быть доступен снаружи
// После запуска вкладка терминала зависнет,
// так как сервер войдёт в режим ожидания входящих запросов
// Если её закрыть или нажать ctrl+c, то сервер остановится
server.listen(3000, '168.123.44.33')

// КЛИЕНТ

// Где-то в другом месте пишем клиент, который запускается отдельно
import net from 'net'

// Для соединения используется сетевой сокет
const client = new net.Socket()
client.connect(3000, '168.123.44.33', () => {
  client.write('Hello, server! Love, client.')
})

// Описываем, что делать, когда придут данные от сервера
client.on('data', (data) => {
  console.log(`Received: ${data}`)
  client.destroy() // отключаемся от сервера
})

// Клиентов можно запустить сколько угодно

Примерно так происходят все сетевые взаимодействия. И даже HTTP отправляется по установленному TCP-соединению.

Рекомендуемые программы