Connect with us

Обучение

Заметки Python #18: Сетевое программирование

182

 

Вот мы и добрались до самого главного — обсуждения взаимодействия между сервером и клиентом. Как они соединяются друг с другом? Какие протоколы нужно использовать и что такое сокет?

Протокол

Сетевое программирование — это та его часть, которая подразумевает обмен данными между сервером и клиентом. При этом клиент и сервер — это не обязательно разные физические сервера, компьютеры, гаджеты. Клиент-серверная архитектура может быть реализована логически, на одном «железе», в одной комнате, за одним столом. Для взаимодействия между ними используется некоторый свод правил по транспортировке, инкапсуляции, очередности пакетов и сетевого взаимодействия — это называется протоколом передачи данных. Приложения, написанные на Python обычно используют протоколы транспортного уровня TCP и UDP.

TCP используют, чтобы формировать между компьютерами двусторонний канал обмена данными. Благодаря TCP пакеты гарантированно доставляются с соблюдением порядка их очередности, с автоматическим разбиением данных на пакеты и контролем их передачи. В то же время TCP работает медленно, так как потерянные пакеты многократно повторно отправляются, а операций, выполняемых над пакетами, слишком много.

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

[adace-ad id=»3470″]

Сокеты

С протоколами разобрались. Но как этими протоколами пользоваться нашим клиентам и сервером? Это взаимодействие осуществляется с помощью сокета. Сокет — абстрактный объект, представляющий конечную точку соединения. . С сокетом в Питоне можно работать, как с файлом — считывать его и получать данные. Сокет содержит в себе два параметра: IP-адрес и порт.

Сервер, принимая соединение присваивает своему сокету определенный порт. Порт — число в заголовках пакетов TCP, UDP, указывающее, для какого приложения в системе предназначен данный IP-пакет.  Использовать порты с номерами 0-1023 нельзя — они зарезервированы под служебные сетевые протоколы (например, 21 — FTP, 80 — HTTP и т.д.). Клиент, отправляя данные тоже должен создать свой сокет. Два сокета с обоих сторон создают виртуальное соединение по которому будет идти передача данных. Нужно отметить, что при работе с протоколом TCP, создается два сокета: один из них — слушающий (listen). Он переходит в режим ожидания и активизируется при появлении нового соединения. При этом можно проверять актуальные активные соединения, установить периодичность операции. Второй — сокет для обмена данных с клиентом (accept). Это два разных сокета, не путайте

[adace-ad id=»3482″]

 

Работа с сокетами в Python

Для создания сокетов в питоне используется модуль socket. В нем так же имеются методы для , установление и закрытие соединения, отправку данных по сети и их получение и другие операции.

 

ОбщиеСерверныеКлиентские
socket — создать сокетbind — привязать сокет к IP-адресу и порту машиныconnect — установить соединение
send — передать данныеlisten — просигнализировать о готовности принимать соединения
recv — получить данныеaccept — принять запрос на установку соединения
close — закрыть соединение

Работа ТСР протокола

Чтобы понять, как с сокетом работает протокол ТСР, посмотрим на изображение ниже. Пояснение будет в коде программы (для примера мы отправляем клиенту текущее время)

Серверная часть:

Функция socket() инициализирует создание сокета. В ней передаются два параметра: communication domain и type of socket. AF_INET — это коммуникационный домен, который задает сетевую направленность нашему сокету. Тип сокета — SOCK_STREAM — он определяет сокет как потоковый, то есть реализующий последовательный, надежный двусторонний поток байтов по протоколу ТСР. Создалась конечная точка подключения — сокет. Функция socket() возвращает нам файловый дескриптор, который позволяет работать с сокетом, как с файлом — записывать и считывать данные в/из него. Метод encode применяется здесь, т.к. данные нужно отправлять по сети в виде байтов.

 

Если вы работаете в среде программирования, то разрешите вашему серверу работать в вашей локальной сети:

Клиентская часть

[adace-ad id=»3475″]

 

Клиент устанавливает соединение с помощью метода connect (в нашем случае, localhost, т.к. сервер и клиент на одной машине). Как мы уже знаем, сервер отправляет нам последовательность кодированных байтов — наша задача декодировать их в строки юникода

 

Результат клиентской части (после запуска сервера):

Результат серверной части (после подключения клиента):

 

Как происходит кодирование/декодирование данных?

Строки, байты, изменяемые строки байтов:

 

Код / данныеРезультат print(type())
i= ‘Data’<class ‘str’> — строка
bi = b’Data’<class ‘bytes’> — строка байтов
ba = bytearray(bi)<class ‘bytearray’> — изменяемая строка байтов
i2 = bi.decode(‘cp1251’)<class ‘str’> — из строки байт в unicode-строку
bi2 = i.encode(‘koi8-r’)<class ‘bytes’> — из unicode-строки в строку байт
ba2 = bytearray(i, ‘utf-8’)<class ‘bytearray’> — из unicode-строки в массив байтов

Отправка и приём сообщений

В качестве примера можно рассмотреть простой механизм отправки сообщений от клиента к серверу и обратно. Сервер получает приветствие от клиента и отправляет ответ клиенту. Клиент, соответственно, отправляет приветствие серверу и получает от него ответ

Серверная часть:

 

Клиентская часть:

 

JSON Instant Messaging

JIM — протокол для обмена данных между клиентом и сервером, который работает через TCP-сокеты (SOCK_STREAM) и передачу JSON-объектов. Все сетевые операции проходят в байтовом представлении. Данные в JSON-формате в протоколе JIM всегда содержат два поля: action и time.

Поле action задает характер действия — авторизация или отправка сообщения и т.п.

Поле time показывает время отправки данного сообщение (используется UNIX-время  — определяется как количество секунд, прошедших с полуночи (00:00:00 UTC) 1 января 1970 года)

JSON-объекты в JIM имеют ограничение по количеству символов. Например, сам текст сообщения ограничен 500 символами. Остальные ограничения:

Поле action — «Действие», 15 символов

Поле response — «Код ответа сервера», 3 символа (цифры)

Поле name — «Имя пользователя  или название чата». Здесь максимум 25 символов;

Весь скомпилированный JSON-объект должен уложиться в 640 символов.

Аутентификация

Для того, чтобы инициализировать процесс аутентификации, надо создать такой JSON-объект:

 

Ответы сервера будут содержать поле response, и может быть еще одно (необязательное) поле alert/error с текстом ошибки.

 

Подключение, отключение, авторизация

Авторизация — не обязательное условие при использовании JIM, т.е. его могут использовать любые пользователи. Если авторизация будет нужна на каком-то этапе, сервер выдаст алерт с кодом 401. Если аутентификация всё же нужна, то сервер может выдать один из нескольких вариантов респонзов:

 

Отключение от сервера должно сопровождаться сообщениемquit:

В сети/ не в сети

Для того, чтобы обозначить своё присутствие в «онлайне», клиент должен отправлять специальное presence сообщение с полем type

 

В свою очередь, сервер посылает специальный probe-запрос для проверки доступности клиента:

Алерты и ошибки сервера

 

КодЧто означает?
1xx — информационные сообщения100 — базовое уведомление; 101 — важное уведомление.
2xx — успешное завершение:200 — OK;  201 (created) — объект создан; 202 (accepted) — подтверждение.
4xx — ошибка на стороне клиента:400 — неправильный запрос/JSON-объект; 401 — не авторизован; 402 — неправильный логин/пароль; 403 (forbidden) — пользователь заблокирован; 404 (not found) — пользователь/чат отсутствует на сервере; 409 (conflict) — уже имеется подключение с указанным логином; 410 (gone) — адресат существует, но недоступен (offline).
5xx — ошибка на стороне сервера:500 — ошибка сервера.

 

Обмен сообщениями

Экшн msg для сервера означает одно — ему надо передать сообщение адресату из поля to. Если не задана кодировка в поле encoding, то сервер будет считывать данные в ascii-формате

Сообщение в «чат»

Тоже самое, что и отправка обычному пользователю, только в поле to ставится решетка с названием чатрума

 

Чтобы зайти в чат:

 

Выйти из чата:

 

Метод Actions

Методы протокола «действия» в  JIM:

“action”: “presence” — присутствие. Сервисное сообщение для извещения сервера о присутствии клиента online;
“action”: “prоbe” — проверка присутствия. Сервисное сообщение от сервера для проверки присутствии клиента online;
“action”: “msg” — простое сообщение пользователю или в чат;
“action”: “quit” — отключение от сервера;
“action”: “authenticate” — авторизация на сервере;
“action”: “join” — присоединиться к чату;
“action”: “leave” — покинуть чат.

Настоятельно рекомендуем ознакомиться с сокетами на Python в материале Хабра — https://habr.com/ru/post/149077/

Нажмите что бы оставить комментарий

Ответить

Ваш e-mail не будет опубликован.

Лучшие сервисы стриминга музыки в 2019 году

Сервисы

Телевидение Wink Ростелеком: Samsung LG, Sony, Phillips, Android TV

Ростелеком

Ноутбуки Asus не видят жесткий диск. Автоматический вход в BIOS при старте

Гаджеты

LG WEB OS: приложения, обновления, настройка, проблемы со звуком

Гаджеты

.

Digital2.ru - Тренды, IT, WEB- разработка, Цифровая экономика
Свободное копирование и распространение материалов с сайта Digital2.ru
разрешено только с указанием активной ссылки на Digital2 как на источник.
Данный сайт в ходит структуру медиа группы: Online Payments Group Intellect Organic
Товарный знак: OPGIO
Copyright 2019 © All rights reserved

Connect
Подпишись на нас