> But moving from TCP to UDP can get you much the same performance without usermode drivers. Instead of calling the well-known recv() function to receive a single packet at a time, you can call recvmmsg() to receive a bunch of UDP packets at once.
TCP is a streaming protocol, there are no datagrams to read one at a time. Nothing stops you from reading the entire kernel buffer (containing multiple HTTP messages) in to userspace in one syscall.