you should read the specs for gnutella 0.6 here
Gnutella Protocol Development
however what a client do when first connects to gnutella is to connect to a bunch of UDP host caches, where ultrapeers ips can be found
upon receiving them, the client tries to connect to the ultrapeers....each ultrapeer responds with a X-Try-Ultrapeers to let the client discover other ultrapeers in the network
so the client can build a database with a good quantity of ultrapeers ips
the difficult part is how gnutella handles queries....I have read about sha1 hashes, query routing tables, etc.... but analyzing limewire communications, I have found it simply send the keywords you type in the search box as query payload
also it is not clear what happens during the downloading of a file....if the client connects directly to the "server" ( the computer that possess the file ) or it connects indirectly through ultrapeers....but I think the download is handled as an out of band communication
someone with a better knowledge of gnutella can shine some light on these topics?