TCP isn't a good messaging protocol
If you look at the most common uses for TCP you find that they include some kind of crude framing, often the three digit FTP request/response codes, to convert what is a simulated full duplex serial stream into a message protocol. This is extraordinarily inefficient. TCP was designed primarily for terminal handling and it relies on innumerable kludges to function reliably, each one of which contributes to surplus traffic and loss of performance. The obvious thing to do about this is to incorporate some kind of block messaging system on top of UDP. It obviously doesn't need to go on top of UDP except that this is convenient -- there are plenty of examples of protocols that were moved from native to UDP so they could be used over the Internet (e.g. SMB, Netware) so there's nothing preventing one from defining a new IP protocol, it will save the minimal overhead of the UDP header, that's all.
Many -- most, in fact -- programmers that use TCP for communications to a device misuse it. They want the convenience of opening a stream socket and sending/receiving data without giving any thought to what's going on further down the stack. Unfortunately, they invariably treat TCP like a message system -- they send a block of data, they expect to receive it. If anything disturbs this datagram like behavior their software misbehaves so you can't fragment or deal with multiple messages in the same stream, they just don't get the idea that its a byte serial transfer (full duplex as well) that isn't formatted as a message unless the application explicitly does so. They see the word 'reliable' and think that's all they need to know. (...and then there's the whole business of dropped sockets.....)