Работа с сокетами.

Сетевые модели

Сетевая модель OSI

Эталонная модель взаимодействия открытых систем описывает уровни сетевого взаимодействия между компьютерами. Данная модель подразумевает семь уровней взаимодействия.

  1. Прикладной
  1. Представления
  1. Сеансовый
  1. Транспортный
  1. Сетевой
  1. Канальный
  1. Физический

Самый низкий уровень взаимодействия — передача информации (битов) между устройствами через сетевые кабеля, радиоканал и пр.

Канальный уровень — подразумевает работу с кадрами (frame) обеспечивая взаимодействие на физическом уровне и контроль ошибок. Именно к этому уровню относяться Ethernet, PPPoE и прочие. К этому уровню также относят драйвер сетевой карты, фактически обеспечивающий взаимодействие канального уровня с сетевым.

Сетевой уровень предназначен для определения пути передачи данных. Отвечает за трансляцию логических адресов и имён в физические, определение кратчайших маршрутов, коммутацию и маршрутизацию, отслеживание неполадок и «заторов» в сети. К этому уровню относяться такие протоколы, как IP, RIP и пр.

Транспортный уровень модели предназначен для обеспечения надёжной передачи данных от отправителя к получателю. К данному уровню относятся протоколы как TCP, UDP.

Сеансовый уровень модели обеспечивает поддержание сеанса связи, позволяя приложениям взаимодействовать между собой длительное время. Уровень управляет созданием/завершением сеанса, обменом информацией, синхронизацией задач, определением права на передачу данных и поддержанием сеанса в периоды неактивности приложений. Сюда относяться протоколы PPTP, SOCKS и пр.

Уровень представления обеспечивает преобразование протоколов и кодирование/декодирование данных. Запросы приложений, полученные с прикладного уровня, на уровне представления преобразуются в формат для передачи по сети, а полученные из сети данные преобразуются в формат приложений. На этом уровне может осуществляться сжатие/распаковка или шифрование/дешифрование, а также перенаправление запросов другому сетевому ресурсу, если они не могут быть обработаны локально.

Прикладной уровень — верхний уровень модели, обеспечивающий взаимодействие пользовательских приложений с сетью. К этому уровню относяться такие протоколы, как HTTP, FTP и пр.

Данная выше модель — эталонная. Реальная же модель, на которой работает современный интернет - стек протоколов TCP/IP

Cтек протоколов TCP/IP

Модель OSI являеться эталонной, в то время, как реально в сетях применяеться TCP/IP, который выглядит следующим образом:

  • Прикладной уровень (Application Layer) HTTP;
  • Транспортный уровень (Transport Layer) TCP;
  • Межсетевой уровень (Сетевой уровень) (Internet Layer) IP;
  • Канальный уровень (Network Access Layer) Ethernet.
    • Физический (непосредственно не относится к TCP/IP)

Программный интерфейс сокет

Сокет — программный интерфейса для обеспечения обмена данными между процессами. Процессы при таком обмене могут исполняться как на одной ЭВМ, так и на различных ЭВМ, связанных между собой сетью. Сокет — абстрактный объект, представляющий конечную точку соединения.

Сокеты бывают клиентские и серверные. Клиентские можно сравнить с конечными аппаратами телефонной сети, а серверные — с коммутаторами. Клиентское приложение (например, браузер) использует только клиентские сокеты, а серверное (например, веб-сервер, которому браузер посылает запросы) — как клиентские, так и серверные сокеты.

Программный интерфейс сокетов в той или иной мере поддерживается всеми современными операционными системами.

Для взаимодействия между машинами с помощью стека протоколов TCP/IP используются адреса и порты. Адрес представляет собой 32-битную структуру для протокола IPv4, 128-битную для IPv6. Номер порта — целое число в диапазоне от 0 до 65535 (для протокола TCP).

Эта пара определяет сокет («гнездо», соответствующее адресу и порту).

В процессе обмена, как правило, используется два сокета — сокет отправителя и сокет получателя. Например, при обращении к серверу на HTTP-порт сокет будет выглядеть так: 194.106.118.30:80, а ответ будет поступать на mmm.nnn.ppp.qqq: xxxxx.

Каждый процесс может создать «слушающий» сокет (серверный сокет) и привязать его к какому-нибудь порту операционной системы (в UNIX непривилегированные процессы не могут использовать порты меньше 1024).

Слушающий процесс обычно находится в цикле ожидания, то есть просыпается при появлении нового соединения. При этом сохраняется возможность проверить наличие соединений на данный момент, установить тайм-аут для операции и т. д.

Каждый сокет имеет свой адрес. ОС семейства UNIX могут поддерживать много типов адресов, но обязательными являются INET-адрес и UNIX-адрес. Если привязать сокет к UNIX-адресу, то будет создан специальный файл (файл сокета) по заданному пути, через который смогут сообщаться любые локальные процессы путём чтения/записи из него. Сокеты типа INET доступны из сети и требуют выделения номера порта.

Обычно клиент явно «подсоединяется» к слушателю, после чего любое чтение или запись через его файловый дескриптор будут передавать данные между ним и сервером.

Клиент на socket

Для работы с сокетами необходимо:

  1. Подключить socket;
  2. Создать сокет
  3. Присоединиться к серверу (для этого необходимо знать адрес сервера и номер порта, к которому Вы присоединяетесь)
  4. Отправить сообщение. Сообщение должно быть битовым: можно получить из строки при помощи метода encode
  5. Получить ответ
import socket                            # Подключаем

sock = socket.socket()                   # Создаём
sock.connect(("<address>", "<port>"))    # Присоединяемся

sock.send("some text data".encode())     # Отправка
data = sock.recv(<data length in bytes>) # Ответ
data = data.decode("utf8")               # раскодируем сообщение в строку

Задачи

Подсоединитесь к серверу 51.250.21.231 на порт - 9000. После того как вы присоединитесь - начинайте общение с сервером:

  • Cервер отправляет вопрос

  • Вы отправляете ответ

  • Cервер отправляет вопрос

  • Вы отправляете ответ

  • ...

    Имя первой задачи — Register

P.S. Для упрощения работы с сервером целесообразно обработку входящих сообщений вынести в отдельный поток, поскольку сервер периодически будет отправлять сразу по несколько запросов.

Например, отдельной нитью (Thread) можно запустить следующую функцию

def listener(sock):
    while sock.fileno() != -1:
        data = sock.recv(1000)
        if len(data) > 0:
            print(data.decode())

RSA

RSA — криптографический алгоритм с открытым ключом пригодный и для шифрования и цифровой подписи. Используется в большом числе криптографических приложений, включая TLS/SSL, который и шифрует HTTP соединение, "превращая" его в HTTPS.

Криптографические системы с открытым ключом используют так называемые односторонние функции, которые обладают следующим свойством:

  • если известно x, то f(x) вычислить относительно просто;
  • если известно y = f(x), то для вычисления x нет простого (эффективного) пути.

Под односторонностью понимается не теоретическая однонаправленность, а практическая невозможность вычислить обратное значение, используя современные вычислительные средства, за обозримый интервал времени.

Шифрование и расшифрование

Предположим, Боб хочет послать Алисе сообщение m.

Сообщениями являются целые числа в интервале от 0 до n-1, т.е m ∈ Zn.

image/svg+xml

Алгоритм шифрования:

  1. Взять открытый ключ (e, n) Алисы
  2. Взять открытый текст m
  3. Зашифровать сообщение с использованием открытого ключа Алисы: c = E(m) = me\modn

Алгоритм расшифрования:

  1. Принять зашифрованное сообщение {displaystyle c} c
  2. Взять свой закрытый ключ {displaystyle (d,n)} (d,n)
  3. Применить закрытый ключ для расшифрования сообщения: m = D(c) = cd\modn
  4. Данная схема на практике не используется по причине того, что она не является практически надёжной (semantically secured). Действительно, односторонняя функция E(m) является детерминированной — при одних и тех же значениях входных параметров (ключа и сообщения) выдаёт одинаковый результат. Это значит, что не выполняется необходимое условие практической (семантической) надёжности шифра.

Наиболее используемым в настоящее время является смешанный алгоритм шифрования, в котором сначала шифруется сеансовый ключ, а потом уже с его помощью участники шифруют свои сообщения симметричными системами. После завершения сеанса сеансовый ключ, как правило, уничтожается.