UDP
UDP (User Datagram Protocol) is message-based.
UDP doesn't guarantee the order in which two separate UDP packets are received, or whether the packets are received at all.
A UDP message (datagram) is always guaranteed to be received as a whole (or not at all, as UDP doesn't guarantee delivery) from recvfrom()
or whatever function you use to read UDP data from a socket. Note that this limits the practical maximum size of a UDP packet to about 512 bytes.
Note that if UDP was stream-based, and the UDP message was split into two packets (datagrams), and the receiver first received the latter half of the message and then the first half of the message, then it would be difficult to stitch together the full message. The receiver might even only receive one half of the message, i.e., drop a packet.
TCP
Unlike UDP, TCP is stream-based. It can split a single message into multiple packets because it guarantees the order in which packets are received. The receiver always receives the first sent packet first, and only then the second packet, making it easier for the receiver to stitch together the full message.
WebSocket
WebSocket runs on top of TCP, but is message-based, like UDP. Therefore WebSocket takes care of preserving message boundaries, like UDP does, and you don't need to parse together a full WebSocket message from multiple separate packets.