3 ms·
> the TCP caller shouldn't have to concern itself with details about checking whether the full message has been received The caller absolutely must concern its
by jacobolus 6y ago
> the TCP caller shouldn't have to concern itself with details about checking whether the full message has been received
The caller absolutely must concern itself with this crucial “detail”. If you do otherwise, your code is broken, full stop.
You can implement a higher-level protocol on top which handles this kind of thing internally and presents a higher-level interface (e.g. not passing any partial data along to its caller until a full message has been received), but if you are just working with TCP directly, what you get is just a stream of bytes. The guarantee you get is that the bytes will be in order and without any gaps.
If you e.g. send UTF-8 encoded text, you must be prepared on the read side to have your stream of bytes cut off arbitrarily in the middle of a character.
- SilasX 6y agoLet function A call TCP read() and pass back a struct that includes the bytes it's received and a flag that indicates whether it's read to the end of the message. Let function B call TCP read() and never return anything until it's received all the bytes of the message. Both of those seem (IMHO) like functions you could have in a TCP library. Neither seems (IMHO) like a higher level protocol.
- jayshua 6y agoThat might be nice. But that's not how it works.
- Matthias247 6y agoThere is no "message" in TCP. So no - you can not have this in a library.
- yuribro 6y agoThe reason that this function doesn't exist is that even if the sender sent a "message" in a single API call, there is no guarantee that the networking code will send it in one IP packet (or one layer 2 frame). We don't want to couple the message size with the lower network protocol, the type of network equipment and so on, and also want to allow merging of messages for more efficient use of the network (If we have a large window size it allows better throughput). So the job of separating the stream into messages is left to the application layer. (unlike for example in UDP, but then you have to worry about dropped messages)
- SilasX 6y agoWhat is that responding to? Of course TCP can split a message across multiple packets of the lower level protocol; that has no bearing on the concepts TCP works in and whether it can indicate end-of-message. If your point is just that TCP doesn't have a concept of a "message" (a bytestream with a clear beginning and ending), then that's fair, but, as I said elsewhere [1] the original comment took for granted that TCP does have a well defined notion of "you've reached the end of the message", or at least, "there is no further data to receive". No one seemed to have a problem with that there, and I was just working off that assumption. As before, I haven't checked whether this is true (I can't quickly verify from descriptions of TCP). And, interestingly enough, there's this comment [2], which says that what I described does exist, but isn't the default. So ... I'm at least not getting a consistent answer to my question, and people who think they know what they're talking about are inconsistent with each other. [1] https://news.ycombinator.com/item?id=23200293 https://news.ycombinator.com/item?id=23200293 [2] https://news.ycombinator.com/item?id=23200906 https://news.ycombinator.com/item?id=23200906
- deleted 6y ago[deleted]
- jacobolus 6y ago> the original comment took for granted that TCP does have a well defined notion of "you've reached the end of the message" No, the original comment was complaining about a coworker who didn’t understand (and refused to listen when told otherwise) that there is no such notion in TCP. It was a response to another comment complaining about people on the internet (e.g. Stack Overflow) too often making the same mistake. You’re more or less playing the part of that coworker here. It’s unclear why.
- yuribro 6y ago> Both of those seem (IMHO) like functions you could have in a TCP library. Neither seems (IMHO) like a higher level protocol. It's responding to the last part. It is a higher level of protocol. In the traditional TCP/IP model, it's in the application level. There are many libraries with an API like you asked, they are just in a higher level. (and TCP_WAITALL is a partial solution, applicable only if you know in advance the exact size of the message you are about to receive)
- jfkebwjsbx 6y agoThose are perfect examples of a higher level protocol, since there is no way you can do it only with TCP.
- scott_s 6y agoIf it makes you feel better, calling read() on a TCP socket is basically the same as calling read() on a file in a file system. In both cases, you can always end up reading less than you expected, and you always must check how much you actually read. In practice, this means that calls to read() for both should always be in a loop.