Why does tcpdump not render ASCII packet data in a human readable format when tcpflow does?

tcpdump and tcpflow are two very different tools with very different purposes. It is true that both capture TCP/IP packets, or read them from pcaps, analyze them, and produce text output. However, tcpdump is primarily focussed on analyzing packet headers, and generally ignores the application payload carried in those packets. In stark contrast, tcpflow is designed to extract the payload, and discard the headers, and reassemble it so that the user can see the byte-stream carried by the TCP connections that exchanged the raw packets.

Note that wireshark undertakes both these tasks simultaneously; in practice, it is difficult and generally not useful to display the entire TCP byte-stream in a single pane, and so wireshark defers to protocol-specific dissectors to break the stream into the messages that the protocol encodes. These can be displayed at the time they were exchanged on the network to give a useful rendering of the protocol conversations as they progressed.

It is possible to get tcpdump to display the packet payload by using its -A flag, in which case you will see the text content of ASCII packet-data in a readable form. However this output still differs from what tcpflow shows: tcpflow will reorder TCP segments according to their sequence numbers and suppress retransmissions, while tcpdump shows that low-level detail that is critical to understanding what is happening at the network layer.

Related

Blog: Cloudy with a Chance of TCP Drops