Команды протокола приводятся неточно - они даны лишь для изложения сути. 

1. Чат:

Чат работает поверх соединения пользователя с хабом. Чат передаётся в виде строк вида:

<ник> сообщение|

2. Приват:

Приваты работают поверх соединения пользователя с хабом, формат сообщений примерно такой:

$From: <кто> $To: <кому>$<кто> сообщение|

3. Чат-комнаты:

С точки зрения DC-клиента чат-комната - обычный пользователь. Чаты есть на самом деле неофициальный способ использовать в приватах ник комнаты в команде.

$From: <комната> $To: <кому>$<кто> сообщение|

4. Активный поиск:

Клиент - хабу: $Search IP:port строка_поиска|

Хаб - всем клиентам: $Search IP:port строка_поиска|

Клиенты - клиенту по протоколу UDP на IP:port: $SR имформация_о_результате_поиска|

(клиент DC++ и все его продолжатели возвращают при активном поиске максимум десять строк $SR)

Отсюда видно, что в активном режиме для поиска нужно настроить входящие пакеты как минимум на один UDP-порт, иначе поиск ничего не найдёт, даже если такие файлы есть. 

5. Пассивный поиск: 

Клиент - хабу: $Search <ник> строка_поиска|

Хаб - всем клиентам с активным коннектом: $Search <ник> строка_поиска|

Клиенты - хабу: $SR результат_поиска|

Хаб - исходному клиенту: $SR результат_поиска|

В пассивном поиске возвращается максимум 5 результатов от каждого клиента. Пассивный поиск при большом количестве клиентов может очень существенно напрягать хаб, поэтому некоторые крупные хабы ограничивают число пассивных клиентов (к примеру, запрещая входить пассивом большему, чем 20% от общего числа пользователей, количеству клиентов). Зато пассивный поиск работает всегда и не требует настройки протокола UDP, проброса портов на роутере, внешнего IP для инета и тд.

Почему хаб ищет только по пользователям с активным коннектом? Потому что пассивный пользователь всё равно не сможет качать у пользователя с пассивным коннектом.

6. Соединение пользователя A (с активным коннектом) с пользователем B (с любым коннектом):

A - хабу: $ConnectToMe ник_клиента IP:port|

Хаб - B: $ConnectToMe ник_клиента IP:port|

B - A по TCP на IP:port: соединение...

По сути A просит B: "A, привет, я B, соединись со мной по IP:port". Видно, что активный коннект требует правильной настройки TCP (а также отсутствие NAT или наличие проброса порта через роутер). В противном случае возникнет Connection timeout. Интересно, что если у B активный коннект, но порт неправильно настроен - соединение всё равно работает! То есть в активном режиме технические проблемы других пользователей качающего мало касаются.

7. Соединение пользователя B (с пассивным коннектом) с пользователем A (с активным коннектом):

B - хабу: $RevConnectToMe ник_B ник_A| 

Хаб - A: $RevConnectToMe ник_B ник_A|

A - хабу: $ConnectToMe ник_B IP:port|

Хаб - B: $ConnectToMe ник_клиента IP:port|

B - A по TCP на IP:port: соединение...

По сути B не может сказать: "A, соединись со мной", поэтому он, наоборот, просит A инициировать соединение - поэтому, начиная с 3 строки, все команды протокола идентичны предыдущему случаю.

Видно, что пассивный коннект не требует от B работы входящих соединений, поэтому он может работать из-за NAT, при включённом firewall и т.д. Зато, в отличие от предыдущего случая, неправильная настройка порта у того, с кем хочешь соединиться, приведёт к полной невозможности соединения.

Если посмотреть внимательно на разницу во взаимодействии в пассивном и активном режиме, станет ясно, почему активный режим существенно лучше.

8. Скачивание файла.

Когда клиент A соединяется с клиентом B, то, вообще говоря, не обязательно пользователь A хочет скачать файл у пользователя B. Бывает и наоборот и даже одновременно. Последний случай особенно интересен. Пусть пользователь A хочет скачать у пользователя B файл, и пользователь B тоже хочет чего-то от пользователя A. При соединении каждый из них выбирает случайное число и сообщает его другой стороне. Тот, у кого число окажется больше, считается победителем и получает право качать первым :)

На практике это выглядит так:

Если клиент A хочет что-то скачать клиента B: $Direction Download число|

Если клиент A не хочет ничего от клиента B, то есть он готов только отдавать: $Direction Upload число|

Если у одной из сторон в Direction стоит Upload, а у другой - Download, то выигрывает второй априори. Если у обоих Download - выигрывает указавший бОльшее число. У обоих Upload быть не может (ибо зачем соединяться, если ни та, ни другая сторона ничего не хочет скачать?).