что такое сокеты python

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

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

Протокол

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

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

что такое сокеты python. Смотреть фото что такое сокеты python. Смотреть картинку что такое сокеты python. Картинка про что такое сокеты python. Фото что такое сокеты python

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

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

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

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

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

что такое сокеты python. Смотреть фото что такое сокеты python. Смотреть картинку что такое сокеты python. Картинка про что такое сокеты python. Фото что такое сокеты python

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

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

# серверная часть
from socket import *
import time

s = socket(AF_INET, SOCK_STREAM) # Создается сокет протокола TCP
s.bind((», 10000)) # Присваиваем ему порт 10000
s.listen(10) # Максимальное количество одновременных запросов

while True:
client, addr = s.accept() # акцептим запрос на соединение
print(client)
print(«Запрос на соединение от %s» % str(addr))
timestr = time.ctime(time.time()) + «\n»
client.send(timestr.encode(‘utf-8’)) #передаем данные, предварительно упаковав их в байты
client.close() # закрываем соединение

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

что такое сокеты python. Смотреть фото что такое сокеты python. Смотреть картинку что такое сокеты python. Картинка про что такое сокеты python. Фото что такое сокеты python

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

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

from socket import *

s = socket(AF_INET, SOCK_STREAM) # создаем аналогичный сокет, как у сервера
s.connect((‘localhost’, 10000)) # коннектимся с сервером
tm = s.recv(1024) # Принимаем не более 1024 байта данных
s.close() # закрываем соединение
print(«Текущее время: %s» % tm.decode(‘utf-8’)) # получаем данные, декодировав байты

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

что такое сокеты python. Смотреть фото что такое сокеты python. Смотреть картинку что такое сокеты python. Картинка про что такое сокеты python. Фото что такое сокеты python

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

что такое сокеты python. Смотреть фото что такое сокеты python. Смотреть картинку что такое сокеты python. Картинка про что такое сокеты python. Фото что такое сокеты python

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

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

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

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

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

from socket import *
import time

s = socket(AF_INET, SOCK_STREAM) # Создаем сокет TCP
s.bind((», 11111)) # Присваиваем порт 11111
s.listen(5) # пять запросов максимум
while True: # пока выполняется условие (пока есть запросы на подключение от клиента)
client, addr = s.accept() # принимаем запрос на соединение
data = client.recv(1000000) # указываем максимальное количество данных, которое можно принять от клиента
print(‘Месседж: ‘, data.decode(‘utf-8’), ‘, пришло от него: ‘, addr)
msg = ‘Купи виски’
client.send(msg.encode(‘utf-8’)) #передаем данные, предварительно упаковав их в байты
client.close()

# клиентская часть
from socket import *

s = socket(AF_INET, SOCK_STREAM) # Создаем сокет TCP
s.connect((‘localhost’, 11111)) # коннект к серверу
msg = ‘Привет, сервер’
s.send(msg.encode(‘utf-8’)) #передаем данные, предварительно упаковав их в байты
data = s.recv(1000000) #получаем не более 1000000 байт
print(‘Сообщение от сервера: ‘, data.decode(‘utf-8’), ‘, длиной ‘, len(data), ‘ байт’) #получаем сообщение от сервера, декодировав байты юникод
s.close()

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. Если аутентификация всё же нужна, то сервер может выдать один из нескольких вариантов респонзов:

<
«response»: 200,
«alert»:»Необязательное сообщение/уведомление»
>

<
«response»: 402,
«error»: «This could be «wrong password» or «no account with that name»»
>

<
«response»: 409,
«error»: «Someone is already connected with the given user name»
>

Отключение от сервера должно сопровождаться сообщением 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 ставится решетка с названием чатрума

Источник

Советы по программированию сокетов в Python.

Во первых этот материал для тех, кто уже пробовал программировать сокеты, а во вторых здесь будет говорится только о сокетах INET (то есть IPv4) STREAM (т.е. TCP), так как они составляют не менее 99% используемых сокетов. От сокета STREAM можно получить лучшую производительность, чем от какого-то другого. Так же приоткроем тайну того, что такое сокет и дадим несколько советов, как работать с блокирующими и неблокирующими сокетами. Начнем разбираться с блокирующих сокетов, т.к. необходимо знать, как они работают, прежде чем работать с неблокирующими сокетами,

Содержание.

Что такое сокет и как он создается?

Грубо говоря, когда происходит переход по ссылке на сайте, браузер делает что-то вроде следующего:

То, что происходит на веб-сервере, немного сложнее. Сначала веб-сервер создает серверный сокет:

Второе замечание: порты с небольшим числом (обычно до 3-х цифр) зарезервированы для «хорошо известных» служб `(HTTPS, SNMP и т. д.), по этому, в качестве номера порта сокета всегда необходимо использовать числа их 4-х цифр, например 8000.

Теперь, когда есть серверный сокет, прослушивающий 443 порт, можно войти в основной цикл веб-сервера:

Существует 3 основных способа, которыми этот цикл может работать:

Подробнее об этом позже. Сейчас важно понять, что это все, что делает серверный сокет. Он не отправляет и не получает никаких данных. Он просто воспроизводит/создает клиентские сокеты. Каждый клиентский сокет создается в ответ на то, что какой-то новый клиентский сокет выполняет подключение sock.connect() к серверу на определенный хост и порт. На этот запрос, сервер создает новый клиентский сокет, и как только он это сделает то сразу возвращается к прослушиванию следующих подключений. Два клиента могут свободно общаться, например на каком-нибудь динамически выделенном порту, который будет закрыт после общения.

Межпроцессорное взаимодействие (IPC).

Использование сокета.

Когда метод Socket.recv() возвращает 0 байтов, это означает, что другая сторона закрыла или находится в процессе закрытия соединения. Следовательно данные из этого подключении больше не будут поступать. Например протокол HTTP/HTTPS использует сокет только для одной передачи. Клиент отправляет запрос, затем читает ответ, сокет закрывается, это означает, что клиент (браузер) может определить конец ответа, получив 0 байтов.

Теперь должно прийти понимание фундаментальной истины сокетов: сообщения должны быть либо определенной фиксированной длины, либо разделены на несколько частей маркерами, либо с указанием длины сообщения (что намного лучше), либо заканчиваться отключением соединения. Выбор полностью за программистом.

В общем, самым простым решением являются сообщения фиксированной длины:

Например можно использовать какой то определенный код отправки практически для любой схемы обмена сообщениями. В Python сокетах ведь отправляются строки, следовательно можно использовать функцию len() для определения их длины. В основном, усложняется код приема.

Если идти по пути сообщений с маркерами, то необходимо получать фрагменты произвольного размера и сканировать полученное сообщение в поисках этих маркеров. Фрагменты по 4096 или 8192 часто хорошо подходят для размеров сетевого буфера. При этом следует помнить об одной сложности: если используемый протокол позволяет отправлять несколько сообщений друг за другом без какого-либо ответа, а вызов Socket.recv() читает произвольный размер фрагмента, то можно в конечном итоге, не чайно, прочитать начало следующего сообщения. В этом случае нужно его запомнить и держать, пока оно не понадобится.

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

Прием/передача двоичных данных.

Закрытие соединения сокета.

Когда умирают сокеты.

Неблокирующие сокеты

Здесь передается в select.select() три списка:

Предупреждение о переносимости: в Unix, модуль select работает как с сокетами, так и с файлами. Не пытайтесь использовать это в Windows. В Windows, модуль select работает только с сокетами. Также обратите внимание, что в языке C многие из более продвинутых параметров сокетов в Windows выполняются иначе. Фактически, в Windows обычно используют потоки, которые работают очень и очень хорошо с сокетами.

Для сокетов из списка writable программа извлекает сообщение из соответствующей очереди message_queues (если есть) и записывает их в сокет. Если в сокете есть ошибка, он удаляет сокет из всех списков опроса ( inputs и outputs ).

Так работают сокеты на низком уровне. В большинстве случаев нет необходимости реализовывать логику на таком низком уровне. Рекомендуется использовать некоторые абстракции более высокого уровня, такие как | Twisted |, | Tornado | или | ZeroMQ |, в зависимости от ситуации.

Источник

Сокеты в Python

Сегодня мы рассмотрим пример программирования сокетов Python. Мы создадим серверные и клиентские приложения на Python.

Программирование сокетов

Чтобы понять программирование сокетов Python, нам нужно знать о трех интересных темах – Socket Server, Socket Client и Socket.

Итак, что такое сервер? Сервер – это программное обеспечение, которое ожидает запросов клиентов и обслуживает или обрабатывает их соответственно.

С другой стороны, клиент запрашивает эту услугу. Клиентская программа запрашивает некоторые ресурсы к серверу, и сервер отвечает на этот запрос.

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

Основная цель этого руководства по программированию сокетов – познакомить вас с тем, как сервер сокетов и клиент взаимодействуют друг с другом. Вы также узнаете, как написать программу сервера сокетов в Python.

Пример

Ранее мы говорили, что клиент сокета запрашивает некоторые ресурсы у сервера, и сервер отвечает на этот запрос.

Итак, мы разработаем и серверную, и клиентскую модель, чтобы каждый мог общаться с ними. Шаги можно рассматривать так:

Сервер сокетов

Мы сохраним программу сервера сокетов, как socket_server.py. Чтобы использовать соединение, нам нужно импортировать модуль сокета.

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

Мы можем получить адрес хоста с помощью функции socket.gethostname(). Рекомендуется использовать адрес порта пользователя выше 1024, поскольку номер порта меньше 1024 зарезервирован для стандартного интернет-протокола.

Смотрите приведенный ниже пример кода сервера:

Итак, наш сервер сокетов работает на порту 5000 и будет ждать запроса клиента. Если вы хотите, чтобы сервер не завершал работу при закрытии клиентского соединения, просто удалите условие if и оператор break. Цикл while используется для бесконечного запуска серверной программы и ожидания клиентского запроса.

Клиент сокета

Мы сохраним клиентскую программу сокета python как socket_client.py. Эта программа похожа на серверную, за исключением привязки.

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

Смотрите ниже пример кода клиента сокета:

Вывод

Чтобы увидеть результат, сначала запустите программу сервера сокетов. Затем запустите клиентскую программу. После этого напишите что-нибудь из клиентской программы. Затем снова напишите ответ от серверной программы.

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

что такое сокеты python. Смотреть фото что такое сокеты python. Смотреть картинку что такое сокеты python. Картинка про что такое сокеты python. Фото что такое сокеты python

Обратите внимание, что сервер сокетов работает на порту 5000, но клиенту также требуется порт сокета для подключения к серверу. Этот порт назначается случайным образом при вызове клиентского соединения. В данном случае это 57822.

Источник

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

Сетевой сокет — это эндпоинт межпроцессного взаимодействия в компьютерной сети. В Python Standard Library есть модуль socket, предоставляющий низкоуровневый сетевой интерфейс. Этот интерфейс является общим для разных языков программирования, поскольку он использует системные вызовы на уровне операционной системы.

Пример Python socket:

Функция возвращает объект сокета, который имеет следующие основные методы:

Здесь мы создаем серверный сокет, привязываем его к localhost и 50000-му порту и начинаем прослушивать входящие соединения.

Код на стороне клиента выглядит проще:

Вместо методов bind() и listen() он вызывает только метод connect() и сразу же отправляет данные на сервер. Затем он получает обратно 1024 байта, закрывает сокет и выводит полученные данные.

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

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

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

Существует множество интерфейсов для разных операционных систем:

Все они примерно одинаковы, поэтому давайте создадим сервер с помощью Python select. Пример Python select :

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

Здесь мы вызываем метод select.select для того, чтобы операционная система проверила, готовы ли указанные сокеты к записи и чтению, и нет ли каких-либо исключений. Метод передает три списка сокетов, чтобы указать, какой сокет должен быть доступен для записи, какой — для чтения и какой следует проверить на наличие ошибок.

Этот вызов (если не передан аргумент timeout ) блокирует программу до тех пор, пока какие-либо из переданных сокетов не будут готовы. В этот момент вызов вернет три списка сокетов для указанных операций.

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

Так работают сокеты на низком уровне. Однако в большинстве случаев нет необходимости реализовывать настолько низкоуровневую логику. Рекомендуется использовать более высокоуровневые абстракции, такие как Twisted, Tornado или ZeroMQ, в зависимости от ситуации.

Источник

Низкоуровневый сетевой интерфейс в Python

Модуль socket обеспечивает доступ к интерфейсу сокета BSD. Он доступен во всех современных системах Unix, Windows, MacOS и, возможно, на дополнительных платформах.

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

Типы параметров функций модуля несколько более высокоуровневые, чем в интерфейсе языка C: как и в случае операций чтения/записи с файлами, распределение буфера при операциях приема данных происходит автоматически, а длина буфера неявно определяется операциями отправки.

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

Пример создания и использования сокетов на примере TCP/IP сервер и клиента.

Этот пример, основанный на стандартной документации библиотеки, принимает входящие сообщения и передает их обратно отправителю. Он начинается с создания сокета TCP/IP, а затем метод sock.bind() используется для связывания сокета с адресом сервера.

Примечание. Для успешного тестирования примера, код клиента и сервера необходимо запускать в разных окнах терминала. Код сервера запускается первым.

TCP/IP сервер.

Клиентская программа настраивает свой сокет иначе, чем сервер. Вместо привязки к порту и прослушивания он использует метод sock.connect() для подключения сокета непосредственно к удаленному адресу.

TCP/IP клиент.

Работа клиента и сервера вместе.

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

Выходные данные клиента показывают исходящее сообщение и ответ сервера.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *