Файловые объекты 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 интерпретируются так же, как и встроенная функция file(). Но мой пример исходного файла работает даже тогда, когда Я говорю 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.makefile
или эта "расширенная" функциональность просто недоступна?
РЕДАКТИРОВАТЬ: 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!"
Я еще не выкопал исходный код, чтобы выяснить разницу между этими двумя версиями, но это может быть подсказкой.