Могу ли я заставить файл socket.makefile иметь ту же семантику чтения, что и обычный файл?

Файловые объекты Python имеют метод чтения, который принимает необязательный аргумент размера, который в основном является максимальным количеством возвращаемых байтов. Например:

fname = "message.txt"
open(fname, "w").write("Hello World!")
print open(fname).read()   # prints the entire file contents
print open(fname).read(5)  # print "Hello"
print open(fname).read(99) # prints "Hello World!"

Итак хотя наш файл содержит менее 99 символов, вызов read (99) немедленно возвращает все доступные данные.

Я бы хотел получить такое поведение для файловых объектов, возвращаемых из socket.makefile . Но если я скажу:

import socket
ADDR = ("localhost", 12345)

listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind(ADDR)
listener.listen(1)

client = socket.create_connection(ADDR)
cf = client.makefile("r+b", bufsize=0)

server, client_addr = listener.accept()
sf = server.makefile("r+b", bufsize=0)

sf.write("Hello World!")
sf.flush()
print cf.read(99)         # hangs forever

Согласно socket.makefile docs, «Необязательные аргументы mode и bufsize интерпретируются так же, как и встроенные -in file () function. " Но мой исходный пример файла работает, даже когда я говорю open (fname," r + b ", 0) , тогда как я не могу найти способ вернуть все доступные данные до указанного количества байтов с помощью псевдо-файла сокета.

Кажется, это отлично работает, если я просто использую socket.recv :

import socket
ADDR = ("localhost", 12345)

listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind(ADDR)
listener.listen(1)

client = socket.create_connection(ADDR)
server, client_addr = listener.accept()

server.sendall("Hello World!")
print client.recv(99)           # prints "Hello World!"

Так есть ли способ сделайте это с помощью socket.makefi le , или эта "расширенная" функциональность просто недоступна?

РЕДАКТИРОВАТЬ: Python 3.2, похоже, работает правильно, хотя синтаксис аргументов socket.makefile , похоже, имеет изменено:

import socket
ADDR = ("localhost", 12345)

listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.bind(ADDR)
listener.listen(1)

client = socket.create_connection(ADDR)
cf = client.makefile("rwb", buffering=0)

server, client_addr = listener.accept()
sf = server.makefile("rwb", buffering=0)

sf.write(b"Hello World!")
sf.flush()
print(cf.read(99))         # prints "Hello World!"

Я еще не копался в исходном коде, чтобы понять разницу между этими двумя версиями, но это может быть намек.

14
задан Eli Courtwright 4 August 2011 в 19:16
поделиться