Đối tượng tệp Python có phương thức đọc có tham số kích thước tùy chọn, về cơ bản là số byte tối đa cần trả về. Ví dụ:Tôi có thể lấy một tệp socket.makefile để có cùng ngữ nghĩa đọc như một tệp thông thường không?
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!"
Vì vậy, mặc dù tệp của chúng tôi có ít hơn 99 ký tự, cuộc gọi tới read(99)
sẽ trả về ngay lập tức với tất cả dữ liệu có sẵn.
Tôi muốn nhận hành vi này trên các đối tượng tệp được trả về từ socket.makefile. Nhưng nếu tôi nói:
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
Theo socket.makefile
docs, "Các chế độ khác nhau và bufsize đối số được giải thích theo cùng một cách như bởi được xây dựng trong tập tin() chức năng." Nhưng ví dụ tệp gốc của tôi hoạt động ngay cả khi tôi nói open(fname, "r+b", 0)
, trong khi tôi không thể tìm ra cách trả về tất cả dữ liệu có sẵn cho đến số byte được chỉ định bằng tệp giả ổ cắm.
Điều này dường như làm việc hoàn toàn tốt nếu tôi chỉ sử dụng 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!"
Vậy có cách nào để làm cho công việc này với socket.makefile
, hoặc là loại chức năng "tiên tiến" chỉ đơn giản là không có sẵn?
EDIT: Python 3.2 dường như cư xử một cách chính xác, mặc dù các cú pháp lập luận để socket.makefile
dường như đã thay đổi:
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!"
tôi đã không đào vào mã nguồn chưa tìm ra sự khác biệt giữa các hai phiên bản, nhưng đó có thể là một gợi ý.
@BrandonRhodes Tôi tin rằng đây là một thay thế khả thi để đóng socket 'sock.shutdown (SHUT_WR) ' – Mazyod