Придание сокетам внешнего вида файлов и потоков ввода-вывода

pridanie soketam vneshnego vida fajlov i potokov vvoda vyvoda Сетевые сценарии

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

В главе 5, например, мы рассматривали сокеты как один из основных механизмов взаимодействий между процессами и потоками, выполняющимися на одном компьютере. А в главе 10 при исследовании возможностей организации взаимодействий между сценариями командной строки и графическими интерфейсами мы написали вспомогательный модуль (пример 10.23), подключающий стандартный поток вывода вызывающей программы к сокету, который мог бы использоваться графическим интерфейсом для приема и отображения вывода. Там я обещал, что мы исследуем подробности, касающиеся дополнительных способов передачи данных, как только достаточно близко познакомимся с сокетами. Теперь, после такого знакомства, в этом разделе мы ненадолго покинем мир сетевых серверов и познакомимся с остальной частью этой истории.

Некоторые программы можно писать или переписывать, явно реализуя в них возможность обмена данными через сокеты, но такое решение подходит не для всех случаев. Для изменения существующих сценариев может потребоваться приложить значительные усилия, а иногда такой подход может воспрепятствовать использованию нужных режимов, не связанных с сокетами. В некоторых случаях лучше было бы позволить сценарию использовать стандартные инструменты работы с потоками ввода-вывода, такие как встроенные функции print и input или методы файлов из модуля sys (например, sys.stdout.write), и подключать их к сокетам только при необходимости.

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

Метод makefile объекта сокета приходит на помощь всякий раз, когда возникает необходимость работать с сокетами с помощью обычных методов файлов или когда необходимо передать сокет существующему интерфейсу или программе, ожидающей получить файл. Объект-обертка, возвращаемый сокетом, позволяет сценариям передавать данные через сокет с помощью привычных методов read и write вместо recv и send. Поскольку встроенные функции input и print используют первую пару методов, они с таким же успехом могут взаимодействовать с сокетами, обернутыми вызовом этого метода.

Метод makefile позволяет также интерпретировать двоичные данные сокета как текст, а не как строки байтов, и может принимать дополнительные аргументы, такие как encoding, что позволяет определять кодировки при передаче текста, отличные от кодировки по умолчанию, как это делают встроенные функции open и os.fdopen, с которыми мы встречались в главе 4, при работе с файловыми дескрипторами. Конечно, при работе с двоичными сокетами текст всегда можно кодировать и декодировать вручную, однако метод makefile снимает это бремя с вашего программного кода и переносит его на обертывающий объект файла.

Такое сходство с файлами может пригодиться, когда необходимо использовать программное обеспечение, поддерживающее интерфейс файлов. Например, методы load и dump из модуля pickle ожидают получить объект с интерфейсом файла (например, с методами read и write), но не требуют, чтобы этот объект соответствовал физическому файлу. Передача сокета TCP/IP, обернутого вызовом метода makefile, методам из модуля pickle позволяет передавать сериализованные объекты Python через Интернет без необходимости выполнять преобразование в строки байтов и вызывать методы сокетов вручную. Этот прием обеспечивает альтернативу использованию строковых методов модуля pickle (dumps, loads) вместе с методами сокетов send и recv и может предложить большую гибкость для программного обеспечения, поддерживающего различные механизмы обмена данными. Дополнительные подробности о сериализации объектов вы найдете в главе 17.

В общем случае любой компонент, ожидающий поддержку протокола методов файлов, благополучно сможет работать с сокетом, обернутым вызовом метода makefile. Такие интерфейсы смогут также принимать строки, обернутые встроенным классом io.StringIO, и любые другие объекты, поддерживающие те же самые методы, что и встроенные объекты файлов. Как это принято в языке Python, мы реализуем протоколы — интерфейсы объектов, — а не определенные типы данных.

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

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