Основы сокетов

osnovy soketov Системные инструменты параллельного выполнения

Сокеты — это один из наиболее часто используемых инструментов IPC, тем не менее невозможно до конца понять их API, не понимая его роль в сетевых взаимодействиях. Вследствие этого я отложу подробное освещение особенностей сокетов, пока мы не исследуем порядок их использования в сетевых приложениях в главе 12. В этом разделе дается краткое введение и предварительный обзор сокетов, благодаря которому вы сможете сравнить их с именованными каналами (fifo), представленными в предыдущем разделе. В двух словах:

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

     В отличие от именованных каналов, сокеты идентифицируются по номеру порта, а не по имени файла в файловой системе, — при работе с ними используется совершенно иной API, не похожий на файлы, тем не менее имеется возможность обертывать их объектами файлов. Сокеты обладают более высокой степенью переносимости: они поддерживаются практически на всех платформах, включая стандартную версию Python для Windows.

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

Пример 5.25. PP4E\System\Processes\socket_preview.py

использует сокеты для обмена данными между заданиями: запускает потоки выполнения, взаимодействующие с помощью сокетов; независимые программы также могут использовать сокеты для взаимодействий, потому что они принадлежат системе в целом, как и именованные каналы; смотрите части книги, посвященные разработке графических интерфейсов и сценариев для Интернета, где приводятся более практичные примеры использования сокетов; некоторым серверам может потребоваться взаимодействовать через сокеты с клиентами в виде потоков выполнения и процессов; данные через сокеты передаются в виде строк байтов, но точно так же через них можно передавать сериализованные объекты или кодированный текст Юникода;

ВНИМАНИЕ: при обращении к функции print в потоках выполнения может потребоваться синхронизировать их, если есть вероятность перекрытия по времени;

from socket import socket, AF_INET, SOCK_STREAM # переносимый API сокетов

port = 50008 # номер порта, идентифицирующий сокет

host = localhost # сервер и клиент выполняются на локальном компьютере

def server():

sock = socket(AF_INET, SOCK_STREAM) # IP-адрес TCP-соединения sock.bind((‘’, port)) # подключить к порту на этой машине

sock.listen(5) # до 5 ожидающих клиентов

подпись: conn, addr = sock.accept() data = conn.recv(1024)while True:

#   ждать соединения с клиентом

#   прочитать байты данных от клиента

reply = ‘server got: [%s]’ % data # conn — новый подключенный сокет

#   подпись: conn.send(reply.encode())отправить байты данных клиенту

def client(name):

подпись: # подключить сокет к порту
# отправить байты данных серверу
# принять байты данных от сервера
# до 1024 байтов в сообщении
sock = socket(AF_INET, SOCK_STREAM) sock.connect((host, port))

sock.send(name.encode())

reply = sock.recv(1024)

sock.close()

print(‘client got: [%s]’ % reply)

подпись: if подпись: name подпись: main



подпись: # не ждать завершения потока сервера
# ждать завершения дочерних потоков
from threading import Thread sthread = Thread(target=server) sthread.daemon = True sthread.start()

for i in range(5):

Thread(target=client, args=(‘client%s’ % i,)).start() Внимательно рассмотрите программный код этого примера и комментарии, чтобы получить представление о том, как используются методы объекта сокета для передачи данных. В двух словах, метод accept сокетов данного типа, который вызывается сервером, принимает соединения от клиентов, по умолчанию блокируя выполнение сервера, пока клиент не пришлет запрос на обслуживание, и возвращает новый сокет, соединенный с клиентом. После установления соединения клиент и сервер приступают к обмену строками байтов с помощью методов приема и передачи, вместо записи и чтения. Однако, как будет показано далее в этой книге, сокеты могут обертываться объектами файлов, как это делалось выше с дескрипторами каналов. Кроме того, подобно дескрипторам каналов, необернутые сокеты работают со строками bytes, а не с текстовыми строками str. Это объясняет, почему результат форматирования строк в примере кодируется вручную.

Ниже приводится вывод этого сценария после запуска в Windows:

C:\\PP4E\System\Processes> socket_preview.py

client got: [b”server got: [b’client1’]”]

client got: [b”server got: [b’client3’]”]

client got: [b”server got: [b’client4’]”]

client got: [b”server got: [b’client2’]”] client got: [b”server got: [b’client0’]”]

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

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Оцените статью
Секреты программирования
Добавить комментарий