To better understand how nmap does service detection, I implemented a tool in Python that tries to do (more or less) the same. nmap detects what service is listening on a port, by sending it probes (particular byte sequences) and matching it with expected replies. These probes and replies can be found in file nmap-service-probes.
It allows me to experiment with service detection.
By default onion-connect-service-detection.py connects to service ports over the Tor network.
Here is an example where I use the tool to detect services on the 10 most popular ports (top:10) of example.com. With a time-out of 5 seconds.