Построчная буферизация

postrochnaya buferizaciya Сетевые сценарии

Файлы-обертки сокетов в текстов ом режиме принимают также значение 1 в аргументе, определяющем режим буферизации, что позволяет определить режим по строч ной буфери за ции вместо режима полной буферизации:

>  >> from socket import *

>  >> s = socket()

>  >> f = s.makefile(‘w‘, 1) # то же, что и buffering=1, но действует

#   как режим полной буферизации!

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

Пример 12.13. PP4E\Internet\Sockets\socket-unbuff-server.py

from socket import * # читает три сообщения непосредственно из сокета

sock = socket()

sock.bind((», 60000))

sock.listen(5)

print(‘accepting…’)

conn, id = sock.accept() # блокируется, пока не подключится клиент

for i in range(3):

print(‘receiving…’)

msg = conn.recv(1024) # блокируется, пока не поступят данные print(msg) # выведет все строки сразу, если не выталкивать

#  буфер вручную

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

Пример 12.14. PP4\Internet\Sockets\socket-unbuff-client.py

import time # отправляет три сообщения через файл-обертку и сокет from socket import *

sock = socket() # по умолчанию=AF_INET, SOCK_STREAM (tcp/ip) sock.connect((‘localhost’, 60000))

file = sock.makefile(‘w‘, buffering=1) # по умолчанию=полная буферизация, # 0=ошибка, 1 не включает построчную # буферизацию!

print(‘sending data1′)

file.write(‘spam\n‘)

time.sleep(5) # следующий вызов flush() должен вызвать немедленную передачу #file.flush() # раскомментируйте вызовы flush(), чтобы увидеть разницу print(‘sending data2′) # дополнительный вывод в файл не приводит print(‘eggs‘, file=file) # к выталкиванию буфера

time.sleep(5) # вывод будет принят сервером только после выталкивания буфера

#file.flush() # или после завершения

print(‘sending data3′) # низкоуровневый двоичный интерфейс выполняет передачу

sock.send(bham\n‘) # немедленно, эта строка будет принята первой, если

time.sleep(5) # в первых двух случаях не выталкивать буферы вручную!

Запустите сначала сервер в одном окне, а затем клиента — в другом (или, в Unix-подобных системах, запустите сначала сервер в фоновом режиме). Ниже показан вывод в окне сервера — передача сообщений, отправленных через файл-обертку сокета, откладывается до завершения программы-клиента, а передача данных, отправляемых через низкоуровневый интерфейс сокета, выполняется немедленно:

C:\\PP4E\Internet\Sockets> socket-unbuff-server.py

accepting

receiving

b’ham\n’

receiving

b’spam\r\neggs\r\n’

receiving

b»

В окне клиента строки «sending» появляются через каждые 5 секунд. Третье сообщение появится в окне сервера через 10 секунд, а передача первого и второго сообщений, отправленных через файл-обертку, будет отложена до завершения клиента (на 15 секунд), потому что файл-обертка действует в режиме полной буферизации. Если в клиенте раскомментировать вызовы метода flush, все три сообщения по очереди будут появляться в окне сервера с интервалом 5 секунд (третье сообщение появится после второго):

C:\\PP4E\Internet\Sockets> socket-unbuff-server.py

accepting

receiving

b’spam\r\n’

receiving

b’eggs\r\n’

receiving

b’ham\n’

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

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

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

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