Сокеты
UDP — это протокол без установления соединения. Сообщения другим процессам или компьютерам отправляются без установления какого-либо соединения. Там нет автоматического подтверждения, если ваше сообщение было получено. UDP обычно используется в приложениях, чувствительных к задержке, или в приложениях, отправляющих широковещательные сообщения в сети.
Следующий код отправляет сообщение процессу, прослушивающему порт localhost 6667 с использованием UDP
Обратите внимание , что нет никакой необходимости «закрыть» сокет после отправки, поскольку UDP является установление соединения .
from socket import socket, AF_INET, SOCK_DGRAM s = socket(AF_INET, SOCK_DGRAM) msg = («Hello you there!»).encode(‘utf-8’) # socket.sendto() takes bytes as input, hence we must encode the string first. s.sendto(msg,(‘localhost’, 6667))
Получение данных через UDP
UDP — это протокол без установления соединения. Это означает, что одноранговые отправляющие сообщения не требуют установления соединения перед отправкой сообщений. socket.recvfrom , таким образом , возвращает кортеж ( msg [сообщение сокет получил], addr [адрес отправителя])
КЛИЕНТ-СЕРВЕРНОЕ ПРИЛОЖЕНИЕ НА PYTHON | ЧАСТЬ 1 | СВЯЗЬ КЛИЕНТА И СЕРВЕРА
UDP — сервер , использующий исключительно socket модуль:
from socket import socket, AF_INET, SOCK_DGRAM sock = socket(AF_INET, SOCK_DGRAM) sock.bind((‘localhost’, 6667)) while True: msg, addr = sock.recvfrom(8192) # This is the amount of bytes to read at maximum print(«Got message from %s: %s» % (addr, msg))
Ниже приводится альтернативная реализация с использованием socketserver.UDPServer :
from socketserver import BaseRequestHandler, UDPServer class MyHandler(BaseRequestHandler): def handle(self): print(«Got connection from: %s» % self.client_address) msg, sock = self.request print(«It said: %s» % msg) sock.sendto(«Got your message!».encode(), self.client_address) # Send reply serv = UDPServer((‘localhost’, 6667), MyHandler) serv.serve_forever()
По умолчанию sockets блока. Это означает, что выполнение скрипта будет ожидать, пока сокет не получит данные.
Отправка данных через TCP
Отправка данных через Интернет возможна с помощью нескольких модулей. Модуль сокетов обеспечивает низкоуровневый доступ к операциям базовой операционной системы, отвечающим за отправку или получение данных с других компьютеров или процессов.
Следующий код посылает строку байт b’Hello’ на сервер TCP на порту 6667 на хосте локального хоста и закрывает соединение после завершения:
from socket import socket, AF_INET, SOCK_STREAM s = socket(AF_INET, SOCK_STREAM) s.connect((‘localhost’, 6667)) # The address of the TCP server listening s.send(b’Hello’) s.close()
По умолчанию вывод сокетов блокируется, это означает, что программа будет ожидать подключения и отправлять вызовы, пока действие не будет «завершено». Для подключения это означает, что сервер фактически принимает соединение. Для отправки это означает только то, что в операционной системе достаточно буферного пространства, чтобы поставить в очередь данные для последующей отправки.
#1 | Python Socket | Как Работает Сеть?
Розетки всегда должны быть закрыты после использования.
Многопоточный сокет-сервер TCP
При запуске без аргументов, эта программа запускается сервер сокета TCP , который прослушивает для подключения к 127.0.0.1 на порт 5000 .Сервер обрабатывает каждое соединение в отдельном потоке.
При запуске с -c аргументом, эта программа подключается к серверу, считывает список клиентов, и выводит его. Список клиентов передается в виде строки JSON. Имя клиента может быть определен путем пропускания -n аргумент. Передавая разные имена, можно наблюдать влияние на список клиентов.
client_list.py
import argparse import json import socket import threading def handle_client(client_list, conn, address): name = conn.recv(1024) entry = dict(zip([‘name’, ‘address’, ‘port’], [name, address[0], address[1]])) client_list[name] = entry conn.sendall(json.dumps(client_list)) conn.shutdown(socket.SHUT_RDWR) conn.close() def server(client_list): print «Starting server. » s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((‘127.0.0.1’, 5000)) s.listen(5) while True: (conn, address) = s.accept() t = threading.Thread(target=handle_client, args=(client_list, conn, address)) t.daemon = True t.start() def client(name): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((‘127.0.0.1’, 5000)) s.send(name) data = s.recv(1024) result = json.loads(data) print json.dumps(result, indent=4) def parse_arguments(): parser = argparse.ArgumentParser() parser.add_argument(‘-c’, dest=’client’, action=’store_true’) parser.add_argument(‘-n’, dest=’name’, type=str, default=’name’) result = parser.parse_args() return result def main(): client_list = dict() args = parse_arguments() if args.client: client(args.name) else: try: server(client_list) except KeyboardInterrupt: print «Keyboard interrupt» if __name__ == ‘__main__’: main()
Выход сервера
$ python client_list.py Starting server.
Выход клиента
$ python client_list.py -c -n name1 < «name1»: < «address»: «127.0.0.1», «port»: 62210, «name»: «name1» >>
Приемные буферы ограничены 1024 байтами. Если строковое представление JSON списка клиентов превышает этот размер, оно будет усечено. Это приведет к возникновению следующего исключения:
ValueError: Unterminated string starting at: line 1 column 1023 (char 1022)
Сырые сокеты в Linux
Сначала вы отключите автоматическую контрольную сумму вашей сетевой карты:
sudo ethtool -K eth1 tx off
Затем отправьте свой пакет, используя сокет SOCK_RAW: « `
Источник: www.codecamp.ru
Веб-сокеты
Серверные события, рассмотренные ранее, являются идеальным инструментом, когда требуется получить последовательность сообщений с веб-сервера. Но при этом связь получается полностью односторонней. Браузер не может отвечать на сообщения или вступать в более сложный диалог с сервером.
Если вы создаете веб-приложение, в котором требуется серьезное двустороннее взаимодействие браузера с веб-сервером, лучшим подходом к его реализации (не прибегая к помощи Flash) будет, возможно, использование объекта XMLHttpRequest. В зависимости от типа создаваемого приложения этот подход может работать так, как требуется. Но здесь существует и достаточное количество возможных проблем.
Прежде всего, объект XMLHttpRequest не очень хорошо подходит для быстрого обмена множественными сообщениями (например, в чате). Потом, в нем нет возможности связать один вызов с другим, поэтому при каждом новом запросе от веб-страницы сервер должен вычислять с самого начала, кому эта страница принадлежит. Поэтому уровень сложности кода для обработки ряда связанных запросов от веб-страницы может очень быстро вырасти до практически нереализуемой.
Для всех этих проблем есть решение, хотя оно еще не вполне готово. Этим решением является технология , которая позволяет браузеру удерживать открытое подключение к серверу и обмениваться сообщениями в течение любого требуемого времени.
Технология веб-сокетов вызвала большое возбуждение в среде веб-разработчиков, но она еще находится в процессе развития, хотя уже имеет неплохую браузерную совместимость:
Браузер | IE | Firefox | Chrome | Safari | Opera | Safari iOS | Android |
Минимальная версия | 10 | 6 | 14 | 6 | 12.1 | 6 | — |
На данный момент лучше всего тестировать страницы, использующие веб-сокеты, в браузере Chrome, который предоставляет наиболее последовательную поддержку для них.
Получение доступа к веб-сокетам
Веб-сокеты являются специализированным инструментом. Они актуальны для таких приложений, как чат, массивные многопользовательские игры или инструмент для пирингового взаимодействия. Веб-сокеты позволяют создавать новые типы приложений, но применять их в большинстве современных веб-приложений, движимых JavaScript, скорее всего, не имеет смысла.
Решения на основе веб-сокетов могут быть чрезвычайно сложны. Разработать JavaScript-код для одной страницы будет достаточно простой задачей. Но для создания серверного приложения вам потребуются бешеные знания и навыки программирования, включая понимание концептов многопоточности и сетевого взаимодействия.
Для использования веб-сокетов на веб-сервере вашего сайта должна исполняться специальная программа, которая будет, как ожидается, называться сервером веб-сокетов. На эту программу возлагается ответственность за координирование взаимодействия всех участников, и после запуска она работает безостановочно.
Многие хостинговые компании не допускают долго работающих программ, если только вы не оплатите выделенный веб-сервер, т.е. сервер, обслуживающий лишь ваш сайт. Если у вас обычный общий хостинг, вы, скорее всего, не сможете размещать на нем страницы, в которых используются веб-сокеты. Даже если вы умудритесь запустить сервер веб-сокетов и удерживать его в рабочем состоянии, владелец вашего хостинга, скорее всего, выявит и выключит его.
Чтобы дать вам представление о масштабе сервера веб-сокетов, рассмотрите некоторые из задач, которые сервер сокетов должен выполнять:
- составить «словарь» сообщений, иными словами, решить, какие типы сообщений являются допустимыми, а какие нет;
- содержать список всех текущих подключенных клиентов;
- выявлять ошибки при отправке сообщений клиентам и прекратить попытки связаться с ними, если кажется, что их больше не существует;
- обрабатывать все данные в оперативной памяти, т.е. данные, доступ к которым может потребоваться всем клиентам, и делать это надежно и безопасно. Здесь имеется обилие возможных неявных проблем, например, когда один клиент пытается присоединиться к обмену, в то время как другой отключается, а информация об обоих хранится в одном и том же объекте в памяти.
Разработчики, скорее всего, никогда не будут сами создавать серверную программу, использующую веб-сокеты, т.к. это просто-напросто не стоит требуемых для этого значительных усилий. Самым легким подходом в этой области будет установить чей-то другой сервер веб-сокетов и разрабатывать свои веб-страницы под него. Так как использование части JavaScript стандарта веб-сокетов не несет трудностей, это не должно доставлять каких-либо проблем.
Другим подходом будет взять чей-либо код сервера веб-сокетов и подогнать его под свои требования. В настоящее время существует великое множество проектов (многие из которых бесплатные и с открытым кодом), в которых разрабатываются серверы веб-сокетов для решения различных задач, на разных языках серверного программирования.
Простой клиент веб-сокетов
С точки зрения веб-страницы функциональность веб-сокетов легко понять и использовать. Первый шаг — это создать объект WebSocket и передать ему URL. Код для этого подобен следующему:
var socket = new WebSocket(«ws://localhost/socketServer.php»);
Строка URL начинается с текста ws://, который идентифицирует подключение типа веб-сокет. Этот URL указывает файл веб-приложения на сервере (в данном случае это сценарий socketServer.php).
Стандарт веб-сокетов также поддерживает URL, которые начинаются с текста wss://, что указывает на требование использовать безопасное, зашифрованное подключение (точно так же, как и при запросе веб-страницы указывается URL, начинающийся с https:// вместо http://).
Веб-сокеты могут подключаться не только к своему веб-серверу. Веб-страница может открыть подключение к серверу веб-сокетов, исполняющемуся на другом веб-сервере, не требуя для этого никаких дополнительных усилий.
Само обстоятельство создания объекта WebSocket понуждает страницу пытаться подключиться к серверу. Дальше надо использовать одно из четырех событий объекта WebSocket: onOpen (при установлении подключения), onError (когда возникает ошибка), onClose (при закрытии подключения) и onMessage (когда страница получает сообщение от сервера):
socket.onopen = connectionOpen; socket.onmessage = messageReceived; socket.onerror = errorOccurred; socket.onopen = connectionClosed;
Например, в случае успешного подключения неплохо бы отправить соответствующее подтверждающее сообщение. Такое сообщение доставляется с помощью метода send() объекта WebSocket, которому в качестве параметра передается обычный текст. Далее приведена функция, которая обрабатывает событие onopen и отправляет сообщение:
function connectionOpen()
Предположительно, веб-сервер получит это сообщение и даст на него ответ.
События onError и onClose можно использовать для отправки извещений посетителю веб-страницы. Но безоговорочно самым важным является событие onMessage, которое срабатывает при получении новых данных от сервера. Опять же, код JavaScript для обработки этого события не представляет никаких сложностей — мы просто извлекаем текст сообщения из свойства data:
function messageReceived(e)
Если веб-страница решит, что вся ее работа выполнена, она может закрыть подключение, используя метод disconnect():
socket.disconnect();
Из этого обзора веб-сокетов можно видеть, что использование сервера веб-сокетов стороннего разработчика не представляет никаких трудностей — нам нужно лишь знать, какие сообщения отправлять, а какие — ожидать.
Чтобы заставить подключение веб-сокетов работать, выполняется большой объем работы за кулисами. Прежде всего, веб-страница устанавливает связь по обычному стандарту HTTP. Потом это подключение нужно повысить до подключения веб-сокетов, позволяющего свободную двустороннюю связь.
На этом этапе возможны проблемы, если между компьютером клиента и веб-сервером находится прокси-сервер (как, например, в типичной корпоративной сети). Прокси-сервер может отказаться сотрудничать и разорвет подключение. Эту проблему можно решить, обнаруживая неудачное подключение (посредством события onError объекта WebSocket) и применяя один из заполнителей (polyfills) для сокетов, описанных на веб-сайте GitHub. Эти заполнители применяют метод опроса, чтобы эмулировать подключение веб-сокетов.
Примеры веб-сокетов в сети
Если вы заинтересованы опробовать веб-сокеты, в сети есть много сайтов, на которых можно запустить свою разработку.
Для начала попробуйте сайт websocket.org, который предоставляет простейший сервер веб-сокетов: веб-страница отправляет ему сообщение, а он возвращает это же сообщение веб-странице:
Хотя этот сервер веб-сокетов и не представляет ничего особенного, на нем вы можете испробовать все возможности объекта WebSocket. Более того, к этому серверу можно подключиться со страницы, расположенной как на промышленном веб-сервере, так и на тестовом веб-сервере на вашем компьютере, или даже со страницы, просто запускаемой с жесткого диска:
Существуют и серверы веб-сокетов, предоставляющие другие возможности, включая следующие:
- Простой чат. Чат, в котором все разговаривают со всеми. Отправляемые сообщения получают все участники чата.
- Многопользовательский альбом. Эта страница объединяет веб-сокеты с HTML5 Canvas. То, что вы рисуете на своем холсте, отображается на холсте других участников, и наоборот. Простой концепт, но очень впечатляющий на практике.
Серверы веб-сокетов
Чтобы иметь возможность испытать свой проект по веб-сокетам, вам нужен сервер веб-сокетов, с которым ваша страница могла бы общаться. Тестовый сервер можно найти во многих местах. Ниже даются ссылки на серверы веб-сокетов для определенных серверных языков:
Этот простой и слегка сыроватый проект будет хорошей отправной точкой для создания сервера веб-сокетов на PHP.
Существует несколько образцов сервера веб-сокетов на Ruby, но этот, применяющий модель «Event—Machine», пользуется особенной популярностью.
Сервер веб-сокетов в виде модуля расширения для Apache на языке Python.
Назвать простым этот всеохватывающий проект нельзя. Но он содержит завершенный сервер веб-сокетов на языке C# на основе платформы .NET корпорации Microsoft.
По своему масштабу этот проект похож на проект .NET, но чисто на языке Java.
В зависимости от того, кого вы спросите, система node.JS для разработки веб-приложений на JavaScript — это либо одна из наиболее перспективных платформ, либо просто разросшийся тестовый инструмент.
В отличие от других пунктов этого списка, Kaazing не предоставляет кода для сервера веб-сокетов. Это развитый сервер веб-сокетов, который можно лицензировать для своего веб-сайта. Для разработчиков, которые предпочитают делать все своими руками, он не будет представлять интереса. Но удобно использовать его на менее амбициозных веб-сайтах, особенно принимая во внимание то обстоятельство, что он содержит встроенную поддержку резервных решений в своих клиентских библиотеках (которые сначала пытаются применить стандарт веб-сокетов HTML5, затем Flash, а потом опрос посредством сценариев на JavaScript).
Источник: professorweb.ru
Работа с сетевыми сокетами на Python
Сетевой сокет — это эндпоинт межпроцессного взаимодействия в компьютерной сети. В Python Standard Library есть модуль socket, предоставляющий низкоуровневый сетевой интерфейс. Этот интерфейс является общим для разных языков программирования, поскольку он использует системные вызовы на уровне операционной системы.
Для создания сокета существует функция, называемая socket . Она принимает аргументы family , type и proto (подробнее см. в документации). Чтобы создать TCP-сокет, нужно использовать socket.AF_INET или socket.AF_INET6 для family и socket.SOCK_STREAM для type .
Пример Python socket:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Функция возвращает объект сокета, который имеет следующие основные методы:
- bind()
- listen()
- accept()
- connect()
- send()
- recv()
Методы bind() , listen() и accept() специфичны для серверных сокетов, а метод connect() — для клиентских. send() и recv() являются общими для обоих типов сокетов. Приведем пример Echo-сервера, взятый из документации:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((‘localhost’, 50000)) s.listen(1) conn, addr = s.accept() while 1: data = conn.recv(1024) if not data: break conn.sendall(data) conn.close()
Здесь мы создаем серверный сокет, привязываем его к localhost и 50000-му порту и начинаем прослушивать входящие соединения.
Чтобы принять входящее соединение, мы вызываем метод accept() , который будет блокироваться до тех пор, пока не подключится новый клиент. Когда это произойдет, метод создаcт новый сокет и вернет его вместе с адресом клиента.
Затем он в бесконечном цикле считывает данные из сокета партиями по 1024 байта, используя метод recv() , пока не вернет пустую строку. После этого он отправляет все входящие данные обратно, используя метод sendall() , который в свою очередь многократно вызывает метод send() . И после этого сервер просто закрывает клиентское соединение. Данный пример может обрабатывать только одно входящее соединение, потому что он не вызывает accept() в цикле.
Код на стороне клиента выглядит проще:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((‘localhost’, 50000)) s.sendall(‘Hello, world’) data = s.recv(1024) s.close() print ‘Received’, repr(data)
Вместо методов bind() и listen() он вызывает только метод connect() и сразу же отправляет данные на сервер. Затем он получает обратно 1024 байта, закрывает сокет и выводит полученные данные.
Все методы сокета являются блокирующими. Это значит, что когда метод считывает данные из сокета или записывает их в него, программа больше ничего делать не может.
Одно из возможных решений — делегировать работу с клиентами отдельным потокам. Однако создание потоков и переключение контекстов между ними — операция не из дешевых.
Для решения этой проблемы существует так называемый способ асинхронного взаимодействия с сокетами. Основная идея состоит в том, чтобы делегировать поддержание состояния сокета операционной системе и позволить ей уведомлять программу, когда есть данные для чтения из сокета или когда сокет готов к записи.
Существует множество интерфейсов для разных операционных систем:
- poll, epoll (для linux)
- kqueue, kevent (для BSD)
- select (кроссплатформенный)
Все они примерно одинаковы, поэтому давайте создадим сервер с помощью Python select. Пример Python select :
import select, socket, sys, Queue server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setblocking(0) server.bind((‘localhost’, 50000)) server.listen(5) inputs = [server] outputs = [] message_queues = <> while inputs: readable, writable, exceptional = select.select( inputs, outputs, inputs) for s in readable: if s is server: connection, client_address = s.accept() connection.setblocking(0) inputs.append(connection) message_queues[connection] = Queue.Queue() else: data = s.recv(1024) if data: message_queues[s].put(data) if s not in outputs: outputs.append(s) else: if s in outputs: outputs.remove(s) inputs.remove(s) s.close() del message_queues[s] for s in writable: try: next_msg = message_queues[s].get_nowait() except Queue.Empty: outputs.remove(s) else: s.send(next_msg) for s in exceptional: inputs.remove(s) if s in outputs: outputs.remove(s) s.close() del message_queues[s]
Как видите, кода гораздо больше, чем в блокирующем Echo-сервере. Это в первую очередь связано с тем, что мы должны поддерживать набор очередей для различных списков сокетов, то есть сокетов для записи, чтения и отдельный список для ошибочных сокетов.
Создание серверного сокета происходит так же, кроме одной строки: server.setblocking(0) . Это нужно для того, чтобы сокет не блокировался. Такой сервер более продвинутый, поскольку он может обслуживать более одного клиента. Главная причина заключается в сокетах selecting :
readable, writable, exceptional = select.select( inputs, outputs, inputs)
Здесь мы вызываем метод select.select для того, чтобы операционная система проверила, готовы ли указанные сокеты к записи и чтению, и нет ли каких-либо исключений. Метод передает три списка сокетов, чтобы указать, какой сокет должен быть доступен для записи, какой — для чтения и какой следует проверить на наличие ошибок.
Этот вызов (если не передан аргумент timeout ) блокирует программу до тех пор, пока какие-либо из переданных сокетов не будут готовы. В этот момент вызов вернет три списка сокетов для указанных операций.
Затем метод последовательно перебирает эти списки и, если в них есть сокеты, выполняет соответствующие операции. Если сокет сервера присутствует в inputs , это значит, что появился новый клиент. Поэтому вызывается метод accept() , далее возвращаемый сокет добавляется к inputs , а также добавляется очередь для входящих сообщений, которые будут отправлены обратно. Если в inputs есть другой сокет, это значит, что сообщения прибыли и готовы к чтению, поэтому метод читает их и помещает в соответствующую очередь.
Для сокетов с возможностью записи он получает сообщения (если они есть) из очереди и записывает их в сокет. Если в сокете есть ошибки, метод удаляет сокет из списков.
Так работают сокеты на низком уровне. Однако в большинстве случаев нет необходимости реализовывать настолько низкоуровневую логику. Рекомендуется использовать более высокоуровневые абстракции, такие как Twisted, Tornado или ZeroMQ, в зависимости от ситуации.
Источник: pythonist.ru
Сокет и его методы
Сокеты являются конечными точками двунаправленного канала связи. Они могут связываться внутри процесса, между процессами на одной машине или между процессами на разных машинах. Аналогичным образом, сетевой сокет является одной конечной точкой в потоке связи между двумя программами, работающими в компьютерной сети, такой как Интернет.
Это чисто виртуальная вещь и не означает никакого оборудования. Сетевой сокет может быть идентифицирован по уникальной комбинации IP-адреса и номера порта. Сетевые сокеты могут быть реализованы на нескольких различных типах каналов, таких как TCP, UDP и так далее.
В терминах сокетов, используемых в сетевом программировании, используются следующие термины:
Домен
Домен – это семейство протоколов, которое используется в качестве транспортного механизма. Эти значения являются константами, такими как AF_INET, PF_INET, PF_UNIX, PF_X25 и т. Д.
Тип
Тип означает тип связи между двумя конечными точками, обычно SOCK_STREAM для протоколов, ориентированных на соединение, и SOCK_DGRAM для протоколов без установления соединения.
протокол
Это может использоваться для идентификации варианта протокола в домене и типе. Его значение по умолчанию равно 0. Обычно оно не учитывается.
Hostname
Это работает как идентификатор сетевого интерфейса. Имя хоста может быть строкой, четырехточечным адресом или IPV6-адресом в двоеточии (и, возможно, точечной).
порт
Каждый сервер прослушивает клиентов, звонящих на один или несколько портов. Порт может быть номером порта Fixnum, строкой с номером порта или названием службы.
Socket-модуль Python для сокет-программирования
Чтобы реализовать программирование сокетов в Python, нам нужно использовать модуль Socket. Ниже приведен простой синтаксис для создания Socket –
import socket s = socket.socket (socket_family, socket_type, protocol = 0)
Здесь нам нужно импортировать библиотеку сокетов, а затем сделать простой сокет. Ниже приведены различные параметры, используемые при создании сокета:
- socket_family – это либо AF_UNIX, либо AF_INET, как объяснялось ранее.
- socket_type – это либо SOCK_STREAM, либо SOCK_DGRAM.
- протокол – обычно не указывается, по умолчанию 0.
socket_family – это либо AF_UNIX, либо AF_INET, как объяснялось ранее.
socket_type – это либо SOCK_STREAM, либо SOCK_DGRAM.
протокол – обычно не указывается, по умолчанию 0.
Методы сокетов
В этом разделе мы узнаем о различных методах сокетов. Три различных набора методов сокетов описаны ниже –
- Методы сокета сервера
- Методы клиентских сокетов
- Общие методы сокетов
Методы сокета сервера
В архитектуре клиент-сервер существует один централизованный сервер, который обеспечивает обслуживание, и многие клиенты получают обслуживание с этого централизованного сервера. Клиенты также делают запрос к серверу. Вот несколько важных методов сокетов сервера в этой архитектуре:
- socket.bind () – Этот метод привязывает адрес (имя хоста, номер порта) к сокету.
- socket.listen () – Этот метод в основном прослушивает соединения, сделанные с сокетом. Запускает TCP слушатель. Backlog является аргументом этого метода, который указывает максимальное количество подключений в очереди. Его минимальное значение равно 0, а максимальное – 5.
- socket.accept () – это примет TCP-клиентское соединение. Пара (conn, address) является парой возвращаемого значения этого метода. Здесь conn – это новый объект сокета, используемый для отправки и получения данных о соединении, а адрес – это адрес, связанный с сокетом. Перед использованием этого метода необходимо использовать методы socket.bind () и socket.listen ().
socket.bind () – Этот метод привязывает адрес (имя хоста, номер порта) к сокету.
socket.listen () – Этот метод в основном прослушивает соединения, сделанные с сокетом. Запускает TCP слушатель. Backlog является аргументом этого метода, который указывает максимальное количество подключений в очереди. Его минимальное значение равно 0, а максимальное – 5.
socket.accept () – это примет TCP-клиентское соединение. Пара (conn, address) является парой возвращаемого значения этого метода. Здесь conn – это новый объект сокета, используемый для отправки и получения данных о соединении, а адрес – это адрес, связанный с сокетом. Перед использованием этого метода необходимо использовать методы socket.bind () и socket.listen ().
Методы клиентских сокетов
Клиент в архитектуре клиент-сервер запрашивает сервер и получает сервисы от сервера. Для этого существует только один метод, предназначенный для клиентов –
- socket.connect (address) – это метод активного интимного подключения к серверу или, проще говоря, этот метод соединяет клиента с сервером. Адрес аргумента представляет адрес сервера.
socket.connect (address) – это метод активного интимного подключения к серверу или, проще говоря, этот метод соединяет клиента с сервером. Адрес аргумента представляет адрес сервера.
Общие методы сокетов
Помимо методов сокетов клиента и сервера, существуют некоторые общие методы сокетов, которые очень полезны при программировании сокетов. Основные методы сокетов следующие:
- socket.recv (bufsize) – как следует из названия, этот метод получает TCP-сообщение от сокета. Аргумент bufsize обозначает размер буфера и определяет максимальный объем данных, который этот метод может получить за один раз.
- socket.send (bytes) – этот метод используется для отправки данных в сокет, который подключен к удаленной машине. Байт аргумента даст количество байтов, отправленных сокету.
- socket.recvfrom (data, address) – этот метод получает данные из сокета. Этот метод возвращает две пары (данные, адрес). Данные определяют полученные данные, а адрес – адрес сокета, отправляющего данные.
- socket.sendto (data, address) – как следует из названия, этот метод используется для отправки данных из сокета. Этот метод возвращает две пары (данные, адрес). Данные определяют количество отправленных байтов, а адрес – адрес удаленного компьютера.
- socket.close () – Этот метод закроет сокет.
- socket.gethostname () – Этот метод возвращает имя хоста.
- socket.sendall (data) – этот метод отправляет все данные в сокет, который подключен к удаленной машине. Он будет небрежно передавать данные до тех пор, пока не произойдет ошибка, и если это произойдет, то он использует метод socket.close (), чтобы закрыть сокет.
socket.recv (bufsize) – как следует из названия, этот метод получает TCP-сообщение от сокета. Аргумент bufsize обозначает размер буфера и определяет максимальный объем данных, который этот метод может получить за один раз.
socket.send (bytes) – этот метод используется для отправки данных в сокет, который подключен к удаленной машине. Байт аргумента даст количество байтов, отправленных сокету.
socket.recvfrom (data, address) – этот метод получает данные из сокета. Этот метод возвращает две пары (данные, адрес). Данные определяют полученные данные, а адрес – адрес сокета, отправляющего данные.
socket.sendto (data, address) – как следует из названия, этот метод используется для отправки данных из сокета. Этот метод возвращает две пары (данные, адрес). Данные определяют количество отправленных байтов, а адрес – адрес удаленного компьютера.
socket.close () – Этот метод закроет сокет.
socket.gethostname () – Этот метод возвращает имя хоста.
socket.sendall (data) – этот метод отправляет все данные в сокет, который подключен к удаленной машине. Он будет небрежно передавать данные до тех пор, пока не произойдет ошибка, и если это произойдет, то он использует метод socket.close (), чтобы закрыть сокет.
Программа для установления соединения между сервером и клиентом
Чтобы установить соединение между сервером и клиентом, нам нужно написать две разные программы на Python, одну для сервера, а другую для клиента.
Серверная программа
В этой программе сокетов на стороне сервера мы будем использовать метод socket.bind (), который привязывает его к определенному IP-адресу и порту, чтобы он мог прослушивать входящие запросы на этот IP-адрес и порт. Позже мы используем метод socket.listen (), который переводит сервер в режим прослушивания. Число, скажем 4, в качестве аргумента метода socket.listen () означает, что 4 соединения остаются в ожидании, если сервер занят, и если 5-й сокет пытается соединиться, то соединение отклоняется. Мы отправим сообщение клиенту с помощью метода socket.send () . В конце мы используем методы socket.accept () и socket.close () для инициирования и закрытия соединения соответственно. Ниже приведена программа на стороне сервера –
import socket def Main(): host = socket.gethostname() port = 12345 serversocket = socket.socket() serversocket.bind((host,port)) serversocket.listen(1) print(‘socket is listening’) while True: conn,addr = serversocket.accept() print(«Got connection from %s» % str(addr)) msg = ‘Connecting Established’+ «rn» conn.send(msg.encode(‘ascii’)) conn.close() if __name__ == ‘__main__’: Main()
Клиентская программа
В клиентской программе сокетов нам нужно создать объект сокета. Затем мы подключимся к порту, на котором работает наш сервер – 12345 в нашем примере. После этого мы установим соединение с помощью метода socket.connect () . Затем с помощью метода socket.recv () клиент получит сообщение от сервера. Наконец, метод socket.close () закроет клиент.
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() port = 12345 s.connect((host, port)) msg = s.recv(1024) s.close() print (msg.decode(‘ascii’))
Теперь, после запуска серверной программы, мы получим следующий вывод на терминал –
socket is listening Got connection from (‘192.168.43.75’, 49904)
И после запуска клиентской программы мы получим следующий вывод на другом терминале –
Connection Established
Обработка исключений сетевых сокетов
Есть два блока, а именно try и за исключением того, который можно использовать для обработки исключений сетевых сокетов. Ниже приведен скрипт Python для обработки исключений:
import socket host = «192.168.43.75» port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.bind((host,port)) s.settimeout(3) data, addr = s.recvfrom(1024) print («recevied from «,addr) print («obtained «, data) s.close() except socket.timeout : print («No connection between client and server») s.close()
Выход
Вышеуказанная программа генерирует следующий вывод –
No connection between client and server
В приведенном выше сценарии сначала мы создали объект сокета. Затем последовало предоставление IP-адреса хоста и номера порта, на котором работает наш сервер – 12345 в нашем примере. Позже используется блок try, и внутри него с помощью метода socket.bind () мы попытаемся связать IP-адрес и порт.
Мы используем метод socket.settimeout () для установки времени ожидания клиента, в нашем примере мы устанавливаем 3 секунды. Используется блок исключений, который будет печатать сообщение, если не будет установлено соединение между сервером и клиентом.
Источник: coderlessons.com