Как подключиться к серверу python

Сокеты в Python для начинающих

Предисловие

В далеком для меня 2010 году я писал статью для начинающих про сокеты в Python. Сейчас этот блог канул в небытие, но статья мне показалась довольно полезной. Статью нашел на флешке в либровском документе, так что это не кросспост, не копипаст — в интернете ее нигде нет.

Как подключиться к серверу python. Смотреть фото Как подключиться к серверу python. Смотреть картинку Как подключиться к серверу python. Картинка про Как подключиться к серверу python. Фото Как подключиться к серверу python

Что это

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

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

Рассмотрим это на простом примере. Представим себе большой зал с множеством небольших окошек, за которыми стоят девушки. Есть и пустые окна, за которыми никого нет. Те самые окна — это порты. Там, где стоит девушка — это открытый порт, за которым стоит какое-то приложение, которое его прослушивает. То есть, если, вы подойдете к окошку с номером 9090, то вас поприветствуют и спросят, чем могут помочь. Так же и с сокетами. Создается приложение, которое прослушивает свой порт. Когда клиент устанавливает соединение с сервером на этом порту именно данное приложение будет ответственно за работу этим клиентом. Вы же не подойдете к одному окошку, а кричать вам будут из соседнего 🙂

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

Сервер

Сейчас создайте два файла — один для сервера, а другой для клиента.

В Python для работы с сокетами используется модуль socket:

Прежде всего нам необходимо создать сокет:

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

Теперь нам нужно определиться с хостом и портом для нашего сервера. Насчет хоста — мы оставим строку пустой, чтобы наш сервер был доступен для всех интерфейсов. А порт возьмем любой от нуля до 65535. Следует отметить, что в большинстве операционных систем прослушивание портов с номерами 0 — 1023 требует особых привилегий. Я выбрал порт 9090. Теперь свяжем наш сокет с данными хостом и портом с помощью метода bind, которому передается кортеж, первый элемент (или нулевой, если считать от нуля) которого — хост, а второй — порт:

Теперь у нас все готово, чтобы принимать соединения. С помощью метода listen мы запустим для данного сокета режим прослушивания. Метод принимает один аргумент — максимальное количество подключений в очереди. Напряжем нашу бурную фантазию и вспомним про зал с окошками. Так вот этот параметр определяет размер очереди. Если он установлен в единицу, а кто-то, явно лишний, пытается еще подстроится сзади, то его пошлют 🙂 Установим его в единицу:

Ну вот, наконец-то, мы можем принять подключение с помощью метода accept, который возвращает кортеж с двумя элементами: новый сокет и адрес клиента. Именно этот сокет и будет использоваться для приема и посылке клиенту данных.

Вот и все. Теперь мы установили с клиентом связь и можем с ним «общаться». Т.к. мы не можем точно знать, что и в каких объемах клиент нам пошлет, то мы будем получать данные от него небольшими порциями. Чтобы получить данные нужно воспользоваться методом recv, который в качестве аргумента принимает количество байт для чтения. Мы будем читать порциями по 1024 байт (или 1 кб):

Как мы и говорили для общения с клиентом мы используем сокет, который получили в результате выполнения метода accept. Мы в бесконечном цикле принимаем 1024 байт данных с помощью метода recv. Если данных больше нет, то этот метод ничего не возвращает. Таким образом мы можем получать от клиента любое количество данных.

Дальше в нашем примере для наглядности мы что-то сделаем с полученными данными и отправим их обратно клиенту. Например, с помощью метода upper у строк вернем клиенту строку в верхнем регистре.

Теперь можно и закрыть соединение:

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

Клиент

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

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

Источник

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

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

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

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

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

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

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

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

TCP/IP сервер.

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

TCP/IP клиент.

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

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

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

Источник

Работа с сетевыми сокетами на 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 3 – Сетевое программирование

Как подключиться к серверу python. Смотреть фото Как подключиться к серверу python. Смотреть картинку Как подключиться к серверу python. Картинка про Как подключиться к серверу python. Фото Как подключиться к серверу python

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

В этой главе вы узнаете о самой известной концепции как программирование сетевых сокетов.

Что такое сокеты?

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

Сокеты могут быть реализованы по нескольким различным типам каналов: сокеты домена Unix, TCP, UDP и т. д. Библиотека socket предоставляет определенные классы для обработки общих транспортов, а также общий интерфейс для работы с остальными.

У сокетов есть своя лексика:

Термины и описание
1Domain – Семейство протоколов, которое используется в качестве транспортного механизма. Эти значения являются константами, такими как AF_INET, PF_INET, PF_UNIX, PF_X25 и т. д.
2type – Тип связи между двумя конечными точками, обычно SOCK_STREAM для протоколов, ориентированных на соединение, и SOCK_DGRAM для протоколов без установления соединения.
3protocol – Обычно нуль, он может использоваться для идентификации варианта протокола внутри домена и типа.
4hostname – Идентификатор сетевого интерфейса:

Модуль socket

Чтобы создать сокет, вы должны использовать функцию socket.socket(), доступную в модуле socket, который имеет общий синтаксис:

Вот описание параметров:

Когда у вас есть объект socket, вы можете использовать необходимые функции для создания своей клиентской или серверной программы. Ниже приведен список необходимых функций:

Способы подключения сервера

Способ и описание
1s.bind() – Этот метод связывает адрес (имя хоста, пару портов порта) сокетом.
2s.listen() – Этот метод устанавливает и запускает прослушиватель TCP.
3s.accept() – Пассивно принимает TCP-клиентское соединение, ожидая, пока не придет соединение (блокировка).

Методы сокета клиента

Способ и описание
1s.connect() – Метод активно инициирует подключение к серверу TCP.

Общие методы сокета

Способ и описание
1s.recv() – Этот метод получает сообщение TCP
2s.send() – Этот метод передает сообщение TCP
3s.recvfrom() – Этот метод получает сообщение UDP
4s.sendto() – Этот метод передает сообщение UDP
5s.close() – Этот метод закрывает сокет
6socket.gethostname() – Возвращает имя хоста.

Простой сервер

Чтобы писать интернет-серверы, мы используем функцию socket, доступную в модуле socket, для создания объекта socket. Затем объект socket используется для вызова других функций для настройки сервера сокетов.

Теперь вызовите функцию bind(hostname, port), чтобы указать порт для вашей службы на данном хосте.

Затем вызовите метод accept возвращаемого объекта. Этот метод ожидает, когда клиент подключится к указанному вами порту, а затем вернет объект connection, который представляет соединение с этим клиентом.

Простой клиент

Давайте напишем очень простую клиентскую программу, которая открывает соединение с портом 12345 и данным хостом. Это очень просто создать сокет клиента, используя функцию модуля socket в Python.

socket.connect(hosname, port ) открывает соединение TCP с Hostname и port. Как только у вас открыт сокет, вы можете читать его, как любой объект ввода-вывода. Когда это будет сделано, не забудьте закрыть его, так как вы закроете файл.

Следующий код – очень простой клиент, который подключается к данному хосту и порту, считывает любые доступные данные из сокета и затем выходит:

Теперь запустите файл server.py в фоновом режиме, а затем запустите файл client.py, чтобы увидеть результат.

Это приведет к следующему результату:

Интернет-модули Python

Список некоторых важных модулей программирования сети/интернета в Python.

ПротоколОбщая функцияНомер портаМодуль Python
HTTPИнтернет страницы80httplib, urllib, xmlrpclib
NNTPНовости сети Usenet119nntplib
FTPПередача файлов20ftplib, urllib
SMTPОтправка электронной почты25smtplib
POP3Получение электронной почты110poplib
IMAP4Получение электронной почты143imaplib
TelnetКомандные строки23telnetlib
GopherПередача документов70gopherlib, urllib

Пожалуйста, проверьте все упомянутые выше библиотеки для работы с протоколами FTP, SMTP, POP и IMAP.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Источник

Заметки 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 ставится решетка с названием чатрума

Источник

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

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