Сокеты — это один из наиболее часто используемых инструментов 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 ожидающих клиентов
while True:
# ждать соединения с клиентом
# прочитать байты данных от клиента
reply = ‘server got: [%s]’ % data # conn — новый подключенный сокет
# отправить байты данных клиенту
def client(name):
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)