问题
When using recv() method, sometimes we can't receive as much data as we want, just like using send(). But we can use sendall() to solve the problem of sending data, how about receiving data? Why there is no such recvall() method?
回答1:
There is no fundamental reason why such a function could not be provided as part of the standard library. In fact, there has been at least one attempt to add recvall().
Given that it can be easily implemented as a loop around recv()
, I don't think that this is a major omission.
回答2:
send
has extra information that recv
doesn't: how much data there is to send. If you have 100 bytes of data to send, sendall
can objectively determine if fewer than 100 bytes were sent by the first call to send
, and continually send data until all 100 bytes are sent.
When you try to read 1024 bytes, but only get 512 back, you have no way of knowing if that is because the other 512 bytes are delayed and you should try to read more, or if there were only 512 bytes to read in the first place. You can never say for a fact that there will be more data to read, rendering recvall
meaningless. The most you can do is decide how long you are willing to wait (timeout) and how many times you are willing to retry before giving up.
You might wonder why there is an apparent difference between reading from a file and reading from a socket. With a file, you have extra information from the file system about how much data is in the file, so you reliably distinguish between EOF and some other that may have prevented you from reading the available data. There is no such source of metadata for sockets.
回答3:
Because recvall
is fundamentally confusing: your assumption was that it would read exactly-N bytes, but I would have thought it would completely exhaust the stream, based on the name.
An operation that completely exhausts the stream is a dangerous API for a bunch of reasons, and the ambiguity in naming makes this a pretty unproductive API.
来源:https://stackoverflow.com/questions/25120761/why-does-python-socket-library-not-include-recvall-method-like-sendall