Пользователь
0,0
рейтинг
18 июня 2010 в 20:10

Администрирование → Пишем простейший торрент трекер на php

Обмен файлами всегда привлекал людей, для этого собственно и был изобретен протокол BitTorrent.

Большинство торрент трекеров написано на PHP, хотя встречаются и такие, которые написаны на C# языке, но для ознакомления мы будем использовать именно PHP.

Давайте рассмотрим что из себя представляет трекер.


Программы называемые бит-торрент клиентами, такие как utorrent, BitTorrent и т.д.

посылают на трекер данные, которые трекер обрабатывает и решает что с ними делать либо вести учет статистики либо выдать пиров (адреса других клиетов участвующих в обмене информацией) для обмена.

Данные передаются GET запросом, для просмотра этих данных вы можете установить http-сниффер например HttpAnalyzerStd.

Анализ показывает что, куда, каким образом передаётся. Примерный вид запроса будет такой:

  1.  
  2. сайт/announce.php?info_hash=%c4N%8f%cc%f4%e5lz%af%7b%b6M%c0%cez%da%25%ac%e7%8f&peer_id=-UT2000-xGv%adq%1b%b7%e4%29%a1%f1%ad&port=57911&uploaded=0&downloaded=0&left=2335117312&corrupt=0&key=AEC92B93&event=started&numwant=200&compact=1&no_peer_id=1
  3.  


Из полученных от клиента данных аннонсер узнает зарегистрирован ли такой торрент на трекере, если да то отдаёт список пиров для файлообмена.

Для того чтобы трекер смог функционировать нам понадобится база данных например mysql.

Создадим таблицу peers чтобы мы могли хранить данные.

  1.  
  2. CREATE TABLE IF NOT EXISTS `peers` (
  3. `info_hash` binary(20) NOT NULL,
  4. `ip` int(11) NOT NULL,
  5. `port` smallint(5) unsigned NOT NULL,
  6. `peer_id` binary(20) NOT NULL,
  7. `uploaded` bigint(20) unsigned NOT NULL default '0',
  8. `downloaded` bigint(20) unsigned NOT NULL default '0',
  9. `left` bigint(20) unsigned NOT NULL default '0',
  10. `update_time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  11. `expire_time` timestamp NOT NULL default '0000-00-00 00:00:00',
  12. PRIMARY KEY  (`info_hash`,`ip`,`port`)
  13. ) ENGINE=MEMORY DEFAULT CHARSET=cp1251;
  14.  


Далее приступаем к PHP

Создаём файл например tracker.php, и работаем с ним.

Соединяемся с базой:

  1.  
  2. <?php
  3. $db_server = 'localhost';
  4. $db_user = 'пользователь базы';
  5. $db_pass = 'Пароль пользователя';
  6. $db_db = 'Имя бызы';
  7. $db_table = 'peers'; //таблица для хранения данных
  8.  
  9. $min_announce_interval = 900; // об этой переменной в следующем посте
  10.  
  11. $max_announce_rate = 500;  // об этой переменной в следующем посте
  12.  
  13. $expire_factor = 1.2; // об этой переменной в следующем посте
  14.  
  15. $scrape_factor = 0.5; // об этой переменной в следующем посте
  16.  
  17. $require_announce_protocol = 'standard'; // об этой переменной в следующем посте
  18. ?>
  19.  


Для того чтобы PHP мог «понимать» и обмениваться с клиентом информацией нам понадобится класс для работы с торрент файлами.

  1.  
  2. <?
  3. require_once 'bencoding.php';
  4. ?>
  5.  


Нам нужно создать функцию которая будет отправлять ответ клиенту в случае неверных данных:

  1.  
  2. <?php
  3. function errorexit($reason) {
  4. exit(bencode(array('failure reason' => $reason)));
  5. }
  6. ?>
  7.  


А также напишем функцию для преобразования ип-адреса 
  1.  
  2. <?php
  3. function resolve_ip($host) {
  4. $ip = ip2long($host);
  5. if (($ip === false) || ($ip == -1)) {
  6. $ip = ip2long(gethostbyname($host));
  7. if (($ip === false) || ($ip == -1)) {
  8. return false;
  9. }
  10. }
  11. return $ip;
  12. }
  13. ?>
  14.  


Поскольку данные у нас будут только текстовые установим:

  1.  
  2. <?php
  3. header('Content-Type: text/plain');
  4. ?>
  5.  


Далее нам нужно проверить все ли данные нам переданы:

  1.  
  2. <?php
  3. if (empty($_GET['info_hash']) || empty($_GET['port']) || !is_numeric($_GET['port']) || empty($_GET['peer_id']) || !isset($_GET['uploaded']) || !is_numeric($_GET['uploaded']) || !isset($_GET['downloaded']) || !is_numeric($_GET['downloaded']) || !isset($_GET['left']) || !is_numeric($_GET['left']) || (!empty($_GET['event']) && ($_GET['event'] != 'started') && ($_GET['event'] != 'completed') && ($_GET['event'] != 'stopped'))) {
  4. errorexit('invalid request (see bitconjurer.org/BitTorrent/protocol.html)');
  5. }
  6. ?>
  7.  


Также проверяем стандарты бит-торрент протокола:

  1.  
  2. <?php
  3. if ($require_announce_protocol == 'no_peer_id') {
  4. if (empty($_GET['compact']) && empty($_GET['no_peer_id'])) {
  5. errorexit('standard announces not allowed; use no_peer_id or compact option');
  6. }
  7. }
  8. else if ($require_announce_protocol == 'compact') {
  9. if (empty($_GET['compact'])) {
  10. errorexit('tracker requires use of compact option');
  11. }
  12. }
  13.  
  14. $ip = resolve_ip(empty($_GET['ip']) ? $_SERVER['REMOTE_ADDR'] : $_GET['ip']);
  15. if ($ip === false) {
  16. errorexit("unable to resolve host name $_GET[ip]");
  17. }
  18. ?>
  19.  


Соединяемся с базой, а также запрашиваем данные:

  1.  
  2. <?php
  3. @mysql_pconnect($db_server, $db_user, $db_pass) or errorexit('Ошибка соединения');
  4. @mysql_select_db($db_db) or errorexit('Ошибка базы');
  5.  
  6. $query = @mysql_query("SELECT COUNT(*) FROM `$db_table` WHERE `expire_time` > NOW();") or errorexit('database error');
  7. $num_peers = mysql_result($query, 0);
  8. $query = @mysql_query("SELECT COUNT(*) FROM `$db_table` WHERE `update_time` > NOW() - INTERVAL 1 MINUTE;") or errorexit('database error');
  9. $announce_rate = mysql_result($query, 0);
  10. $announce_interval = max($num_peers * $announce_rate / ($max_announce_rate * $max_announce_rate) * 60, $min_announce_interval);
  11. ?>
  12.  


Проверяем какое событие (остановлен, запущен):

  1.  
  2. <?php
  3. if (!empty($_GET['event']) && ($_GET['event'] == 'stopped')) {
  4. $expire_time = 0;
  5. }
  6. else {
  7. $expire_time = $announce_interval * $expire_factor;
  8. }
  9. ?>
  10.  
  11.  


Вставляем/обновляем данные в базе

  1.  
  2. <?php
  3. $columns = '`info_hash`, `ip`, `port`, `peer_id`, `uploaded`, `downloaded`, `left`, `expire_time`';
  4. $values = '\'' . mysql_escape_string($_GET['info_hash'])  . '\', ' . $ip . ', ' . $_GET['port'] . ', \'' . mysql_escape_string($_GET['peer_id']). '\', ' . $_GET['uploaded'] . ', ' . $_GET['downloaded'] . ', ' . $_GET['left'] . ", NOW() + INTERVAL $expire_time SECOND";
  5. @mysql_query("REPLACE INTO `$db_table` ($columns) VALUES ($values);") or errorexit('database error');
  6. ?>
  7.  


Получем список пиров, с таким же info_hash:

  1.  
  2. <?php
  3. $peers = array();
  4. $numwant = empty($_GET['numwant']) ? 50 : intval($_GET['numwant']);
  5. $query = @mysql_query("SELECT `ip`, `port`, `peer_id` FROM `$db_table` WHERE `info_hash` = '" . mysql_escape_string($_GET['info_hash']) . "' AND `expire_time` > NOW() ORDER BY RAND() LIMIT $numwant;") or errorexit('database error');
  6. if (!empty($_REQUEST['compact'])) {
  7. $peers = '';
  8. while ($array = mysql_fetch_assoc($query)) {
  9. $peers .= pack('Nn', $array['ip'], $array['port']);
  10. }
  11. }
  12. else if (!empty($_REQUEST['no_peer_id'])) {
  13. while ($array = mysql_fetch_assoc($query)) {
  14. $peers[] = array('ip' => long2ip($array['ip']), 'port' => intval($array['port']));
  15. }
  16. }
  17. else {
  18. while ($array = mysql_fetch_assoc($query)) {
  19. $peers[] = array('ip' => long2ip($array['ip']), 'port' => intval($array['port']), 'peer id' => $array['peer_id']);
  20. }
  21. }
  22. ?>
  23.  
  24.  


Ну и наконец отправляем данные клиенту:

<?php

exit(bencode(array('interval' => intval($announce_interval), 'peers' => $peers)));

?>

Malerok @Malerok
карма
–1,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Администрирование

Комментарии (100)

  • –1
    Под кат бы неплохо…
    • +6
      Сделано
    • –85
      Убрать бы это говно с хабра не плохо)
      А то ПэХэПэ программисты действительно считают что:
      «Большинство торрент трекеров написано на PHP, хотя встречаются и такие, которые написаны на C# языке, но для ознакомления мы будем использовать именно PHP.»
      =) бугагагашеньки
      • +7
        как бы не на С# а на С или С++, и как бы не весь торрент а только анонсер и все
        • –1
          Торрент трекер в контексте статьи это и есть скрап+аннонсер А всё остальное это сопутствующие рюшки.
          Наиболее популярным С++ торрент-_трекером_, поддерживающим миллиарды пиров является xbtt.sourceforge.net/
          • +1
            кэп я в курсе, как бы почитай мой пост, где я и говорил про С++
          • 0
            >поддерживающим миллиарды пиров
            миллиарды одновременных соединений или миллиард записей в БД? если последнее, то в этом только заслуга БД.
            • 0
              Миллиарды имелось в виду в целом по всему интернету.
              Там нет БД. Пиры хранятся в структуре данных в памяти. Вот тут можно почитать, если интересно: habrahabr.ru/blogs/server_side_optimization/53360/
      • +5
        Друг ты в курсе процентов 90 самых посещаемых, с многомилионными аудиториями, проекты начинали/до_сих_пор работают на связке php+mysql? Многие, при возрастании нагрузок, частично переписывают «узкие» места на тот же C++, но многое и остается, а кто-то вообще не переписывает, оптимизируя код, обвязки, расширяя каналы и т.д.

        Хороший язык — это не тот, который «красиииииииииивооооо», а тот, который «целесообразно». И статистика в этом плане не обманывает. Спроси википедию (которая кстати тоже php+mysql если мне память не изменяет).
        • –29
          Ой и вы наверное в курсе что когда-то давно, в старадавние времена катались на лошадях)
          Сейчас, тоже кто — то считает что на них целесообразно передвигаться по центру города, угу )
          • +8
            Немного надуманное сравнение, уж извините ) Как быть с тем, что и сейчас и, уверен, через год-два, те-же 80-90% новых проектов под веб (в т.ч. изначально предполагающие высокие нагрузки) будут писаться на PHP?

            Как правильно заметил комментатор ниже, PHP — отличный инструмент в умелых руках, просто его «ауру» портит крайне низкий порог вхождения (хотя лично я не считаю что это плохо), рождающий большое количество довольно грубых поделок, некоторые из которых обретают популярность.

            Ведь и обычным молотком можно размозжить все пальцы себе, а можно, при должной сноровке и умении, сколотить прекрасный кухонный гарнитур к примеру ;-)
          • +3
            Ну катаются на лошадаях, и что? И нормально, между прочим. Иногда это целесообразней.
      • +8
        Вы правы что «непрофессионализм» желательно с хабра убрать (система рейтингов/кармы/итд для этого и придумана) но РНР тут не при чём, то что среди РНР-программистов очень много ламеров, вовсе не значит что таковые все.

        Возможно я поиграю роль «капитана очевидность» и открою Америку, но на РНР действительно можно писать грамотный (читабельный и масштабированный) код. И тот факт что таковой пишут далеко не все, вовсе не недостаток языка, а лишь факт с которым надо смириться (в других языках тоже ламерья полно, просто среди РНР-шников его чуть больше в силу популярности языка)
        • НЛО прилетело и опубликовало эту надпись здесь
      • –1
        Хотелось бы не только коменту минус влепить но и на лбу Вам
      • –3
        согласен! =)
      • –1
        тебя бы с Хабра убрать для начала
  • +1
    В клиенте адрес трекера должен быть такой ваш_сайт/tracker.php, данные будут передаваться туда. Данный трекер предназначен в первую очередь для малых сетей, где нет нужды использовать крупные трекеры вроде торрентпира, и xbtt
  • +2
    Вы забыли рассказать о классе, который работает с торрент файлами, который в bencoding.php.
    • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Дико извиняюсь, пост обновлен.
  • +2
    Где он простейший?

    Простейший это когда в нём только самый минимум (я такой писал, 670 байт РНР кода было, но он был дырявый, по этому сейчас работает такой-же простой но уже на 2.5кб кода)

    Однако он совершенно не имеет никакого смысла ибо есть DHT (трекер в наше время нужен для ограничений, по ратио итд, по этому писать «простейший» уже нет никакого смысла, только в обучающих целях)
    • 0
      Здесь приведен простой пример для работы с некоторыми функциями, которые приносят пользу. На размер файла не смотрел, но проще думаю некуда.
  • +11
    Проще и не надо, более того код настолько кривой что лучше бы чего-то посложнее. Даже обилие собак в коде и то зашкаливает, а уж остальное.

    Но ладно, по пунктам
    — Если это показательный пример, где комментарии?
    — Если это пример для реального проекта, почему ошибки сервера (типа «database error») которые должен видеть только программист, выдаются клиенту?
    — Нафига такие развратные проверки всего и вся? (info_hash надо проверять сначала на isset потом на strlen, никаких empty ибо стандарт предусматривает фиксированную длинну)
    — Почему не проверяется «magic_quotes»

    Я могу долго продолжать, но пока остановимся на этом…
    • –2
      Как я уже писал, это лишь те простейшие вещи которые можно делать благодаря php естествено такой код на рабочую машину ставить можно для проверки работоспособности нельзя. Кому надо может поправить различные проверки входящих данных. Как для ознакомления код по моему само-то. А насчет комментариев, вы можете найти описания функций на php.su :)
      • +1
        Ни на один из четырёх вопросов не прозвучал ответ.

        Задам ещё и пятый вопрос «Нафига это тогда всё надо, если код этот не показательный, и ставить тоже его нельзя ?»
        • +2
          Вы считаете, что данный материал будут читать люди незнающие абсолютно ничего о php? Я думаю что если человеку что-то нужно для создания того или иного он берет материал и складывает его, в сумме получает нужный продукт, спасибо конечно и за ваши вопросы.

          >>— Если это показательный пример, где комментарии?
          Комментарии есть, посмотрите между кодом, если кому-то что то будет неясно, я дополню.

          >>— Если это пример для реального проекта, почему ошибки сервера (типа «database error») которые должен видеть только программист, выдаются клиенту?
          Для реального проекта каждый работает напильником под себя.

          >>— Нафига такие развратные проверки всего и вся? (info_hash надо проверять сначала на isset потом на strlen, никаких empty ибо стандарт предусматривает фиксированную длинну)
          Для проверки верности данных! Я сам рассматривал что и как передаёт клиент трекеру, поэтому и функции не убрал, вообще люблю извращаться над такими вещами.
          >>— Почему не проверяется «magic_quotes» это уже дополнение к теме.
          • +4
            Я считаю:
            — Если код всё же «показательный», и его будут читать новички, то он должен быть «максимально крут»
            (ибо обучив новичка ставить собак в коде, вы рождаете очередного «быдлокодера»)
            — Если код для профи, то в нём должна быть «фишка» (либо уж он должен быть минимален, либо максимален, либо «мега крут»)

            Так и не могу понять зачем ЭТО выложено в блоге. (ни демонстрационной, ни пользовательской, ни даже извращенской ценности, сей код не имеет.)
            • 0
              Какая фишка может быть в том, что получил гет/выдрал с базы / отдал || не отдал пиров?
              Вам возможно нет никакой пользы, если есть желание напишите подобный пост где будут учтены все ваши потребности, я с удовольствием посмотрю на сие детище.
              • +4
                Писал, получил свою честно заслуженную порцию минусов, и осознал что писатель из меня ничуть не лучше чем из Вас. =)

                А «фишка» может быть в любом даже неожиданном месте, почитайте хабр. Кто-то на батниках BMP файлы генерирует, кто-то умудряется в 100 байт кода уложить полнофункциональную программу, кто-то ещё что-то. Короче простора для фантазии куча, вовсе не обязательно чтоб код был идеален, разврат тоже в почёте. Однако приведённый тут трекер, не имеет никакой «фишки». (Ни качественной, ни развратной.)
          • 0
            Лучше остановимся на том, что Вы «любите извращаться» :)
            • 0
              В том то и дело что даже извращения тут нет, просто код новичка, никакого разврата тут нет…
          • 0
            Если вас не забанил гугл, спросите у него, как с помощью китайского символа можно обойти escape_string, и почему сисьадмины любят правило «запрещено все, кроме разрешенного», а не «разрешим все, запретим немного».
  • +6
    «Обмен файлами всегда привлекал людей, для этого собственно и был изобретен протокол bit-torrent»

    BitTorrent изначально создавался скорее для распространения больших объемов информации. И пишите название правильно.

    «Данные передаются GET запросом, для просмотра этих данных вы можете установить http-сниффер например HttpAnalyzerStd. Анализ показывает что, куда, каким образом передаётся. Примерный вид запроса будет такой:»

    СНИФФЕР? А спецификации/документацию уже запретили читать или это не так модно?
    • 0
      Спасибо за замечание, BitTorrent поправлен, а насчет сниффера мне как то лучше, когда все происходит вживую, хотя для тех, кто хочет почитать может обратиться к вики (http://en.wikipedia.org/wiki/BitTorrent_%28protocol%29)
      • +1
        Не поверишь, но по спецификации намного проще (ибо не просто «какие-то символы» а с объяснениями, зачем, почему, зачем и в каких случаях)
        • 0
          А вы попробуйте перейти на трекер для отладки, например забыл поставить ";" и что в итоге? В клиенте будет «Трекер отправляет неверные данные» как вы поступите в таком случае? Проще перейти по ссылке сделанной сниффером, в которой существуют гет параметры, такие как info_hash, downloaded и прочее, перейдя по данной ссылке мы получим ошибку.
          • 0
            йуный хакир детектид :D
      • 0
        Слушая канал, Вы никогда не может быть уверены, что знаете протокол на 100%, т.к. всегда существует вероятность, что существуют запросы, которые отправляются только в определенных случаях и которые Вы просто не видели. Равно как и коды ошибок etc
  • +3
    не минусую и не плюсую. первое — потому что тема близка, второе — потому что особо не за что. Код привели, это вроде правильно, но лучше бы написали статью о концепции, с пояснениями, а код реализации приложили бы.

    выучить php — это пустяк, научится его грамотно использовать — это уже опыт. а то придет какой-нить школьник, скопипастит и потом будет гордится, какой у него крутой трекер, а понимать, как он работает не будет… и станет потом одним из многих…
    • 0
      С вами совершенно согласен, но без понятия основ, при возникновении какой либо ошибки он и отладить её не сможет. А насчет более правильного излогания мыслей учту, писать красивые посты пока не очень получается, но развиваемся. :)
      • 0
        Короче говоря, отполируйте код, и будет четко

        1. форматирование. отступы, табуляции (linux, ff3 — все без отступов, читать тяжело)
        2. грамотная структура кода. если уж процедурный подход — то тогда разнесите по смыслу: вот тут проверка, вот тут — работа с базой, вот тут — подготовка запросов; выше слоем — вот функция, которая выводит то-то, а вот — которая выводит сё-то.
        3. а еще лучше написать и обработать обфускатором. перенеся в блог Ненормальное программирование. Или в Занимательные задачи — сломай себе мозг, восстанови код моего торрент-трекера (кстати через дефис, по-моему, пишется).
  • –1
    Автор конечно молодец, но сразу же бросаются в глаза, не экранированные переменные
    $_GET['port'],$_GET['left'],$_GET['downloaded'].
    • 0
      Ойой, увидел где идет проверка =) Ну так понатыкать кода, в один if — жестоко :)
  • –1
    Я понимаю, конечно, что пятница — но зачем этот быдло-код здесь?!
  • –6
    Зачем "?>"?
    • –2
      А че вы его минусуете то? Человек дело говорит.
      Мелоч конечно, но штука лишняя.
      • 0
        Ну это всё равно что написать в конце echo '';
        • +2
          а я в конце каждого скрипта пишу ретурн :-Р
          • –1
            <?
            $return="";
            return=''.$return."";
            ?>
            А я вот так пишу :-P
            • +4
              а я томат
              • –6
                Мальчик, ты дол… б!

                оригинал: Дети: — А я — вишенка… — А я — яблочко… — А я — томат… — А я — дол… б…

                Мальчик!!! Ты — БАКЛАЖАН!!!

                Еще раз: — А я — вишенка… — А я — яблочко… — А я — томат… — А я — долб...…

                Мальчик!!! Повторяю — Ты — БАКЛАЖАН!!!

                Еще раз: — А я — вишенка… — А я — яблочко… — А я — баклажан!!!

                Мальчик!!! Ты — дол… б!!! Сначала идет — ТОМАТ!!!

                Я слива лиловая, спелая, садовая!

                — А я абрикос, на юге рос!

                — А я томат! Вместе мы фруктовый сад!

                Вбегает девочка:

                — Фруктов нету ни х.., пейте сок «Моя семья»!

                — Девочка, сколько можно повторять? «А я фейхуя, пейте сок „Моя семья“!»

                Выбегает снова:

                — А я фея без х..., пейте сок «Моя семья»!

                — Девочка, не без х… а просто — фейхуя!

                Выбегает ещё раз:

                — А я просто без х.., пейте сок «Моя семья» )))
                • +1
                  А Вы мне не тычьте =) Приезжайте и мы на вас посмотрим.
            • 0
              А зачем? Кстати говоря ?> рождает проблемы т.к. в некоторых случаях к файлу може добавиться перевод строки (например при заливке по ftp в text-mode). Ну и перевод строки уйдет в вывод, что может родить проблемы с дальнейшей отправкой заголовков.
            • 0
              это что такое? о_0"
          • 0
            Ну если файл инклюдится то имеет смысл это делать, иначе — нет.
  • 0
    Интересно, а что будет в следующем посте? Могли бы эти 5 несчастных переменных (ведь пять?) здесь уже описать. Информация абсолютно нулевая. Или это урок «как не надо писать на php»?
  • +2
    "...empty($_GET['info_hash']) || empty($_GET['port']) || ...." убивал бы -_-
  • +1
    Где же всё ООП и абстрактное мышление?

    Использование $_REQUEST как бы намекает, что программисту «не известно» с какими данными он работает.

    if ($require_announce_protocol == 'no_peer_id') — здесь хорошо бы использовать константы const NO_PEER_ID = 'no_peer_id' и сравнивать с ней. Ещё лучше если константа классовая (см. про ООП).

    Перебор параметров в листинге 8 это просто жуть жутчайшая:
    <?php
    if (empty($_GET['info_hash']) || empty($_GET['port']) || !is_numeric($_GET['port']) || empty($_GET['peer_id']) || !isset($_GET['uploaded']) || !is_numeric($_GET['uploaded']) || !isset($_GET['downloaded']) || !is_numeric($_GET['downloaded']) || !isset($_GET['left']) || !is_numeric($_GET['left']) || (!empty($_GET['event']) && ($_GET['event'] != 'started') && ($_GET['event'] != 'completed') && ($_GET['event'] != 'stopped')))

    Не сомневаюсь, что всё это работает, но тем не менее реализация ужасна — нечитабельный, трудноподдерживаемый код, как следствие — немасштабируемое приложение.
    • +1
      Думаю, что эта статья имеет другие цели. Он же не готовый скрипт трекера выкладывает ради скрипта трекера. А показывает как с ним работать. И если бы это был ООП код, то пост был бы немного больше. И менее понятен для новичков. А для кого эта статья прежде всего? Именно для новичков.
      Ну а код можно было было бы поаккуратней написать, конечно)
      • +1
        Вообще не аргумент. Давайте писать плохой код, если это: «для себя», «для других целей», «временное решение», «на скорую руку», «фсем похуй»? Так и рождаются проекты, которые нереально поддерживать и развивать, так и остаются программисты на уровне *новичков*.

        Новичков нужно учить писать код правильно и давать правильные примеры, иначе из «новичков» не вырастут. статья про peer-to-per — вот и нужно было подробности реализации трекера и механизм его работы расписать, код вообще лишний («статья имеет другие цели»). А откомментированный код можно приаттачить или выложить на гуглокоде/гитхабе.

        Самое интересное, что Ваш единственный аргумент «для новичков» разбивается в дребезги — для них эта каша тоже непонятна, как раз потому что логика и структура не прослеживаются.
        • +4
          Настоящий программист никогда не ставит комментариев,
          что писалось с трудом, должно читаться с трудом :) © анекдот
          • –2
            Помимо всего хорошего, чему учится программист, он учится документировать свой код. Или системы документирования и порты javadoc для слабаков?)
        • 0
          Ну во многом Вы правы.
  • +3
    говнокод очень в стиле пхп х)
    • +1
      Ничего подобного. Рискую — но говнокод в стиле говнокодеров, если у человека каша в голове, то такая же каша будет и в коде. Может быть и сложно в это поверить, но «с использованием пхп» © можно писать вполне себе. Хотя низкий порог вхождения и дизайн языка не то чтобы располагают, а не ограничивают в наклаживании кода и подобном скриптоложестве ))
      • 0
        ну так пхп — это одна большая каша ;-) кое как названные функции, кое как прикрученный ооп…
        • +2
          Тем не менее он позволяет успешно решать те задачи, для которых используется. Беда его в том, что из простого шаблонизатора он стал очень популярным простым шаблонизатором, который начали использовать шире, чем изначально предполагалось. Это видно по тому, как язык развивается. И тем не менее знаменитую цитату про «использование языка» © не просто так упомянул: пишет всегда программист, и нечего на инструмент пенять — ведь можно было выбрать другой ;)
    • 0
      Не в стиле пхп, а в стиле человека который начал свой путь в программирование с пхп, и застопорился на самом старте ^_^
  • +2
    Ох и наговнокодили…
  • +2
    Только вчера читал данную статью на сайте:
    cma-cms.ru/2010/06/10/pishem-prostejshij-torrent-treker-na-php/

    Вы автор сайта?
    • +3
      Бог с ним, что Вы-то там делали?))
      • +2
        Случайно наткнулся в гугле, когда искал информацию на тему как написать торрент трекер %)
        Сейчас хабр на 2 месте висит.
  • +2
    PHP — это работа, красивый код — это искусство. Открою тайну — хабр написан на PHP. O_o
    • +2
      o_O я думал на бейсике ((( Вы меня разочаровали…
  • +3
    Удивительно — но я угадал о чем топик и что там именно, начав читать.
    Насчет PHP — язык клевый, зарабатываю как раз за счет программинга на нем. Хотя только сегодня подписал на защиту диплом клиент-серверного приложения на плюсах с интеграцией с приложением на своем фреймворке PHP.

    Итак, почему говнокод — это плохо. Не потому, что код плохой в плане алгоритмов или ООП. Я не дрочу на правильность.
    Я дрочу на ПОДДЕРЖКУ. Знаете, почему Джумла — херь и полное, отвратительное говно, а какой-нибудь Livestreet — суперняшный продукт? Потому что МОДИФИЦИРОВАТЬ последний — одно удовольствие.

    Я думаю, именно с этим связана нелюбовь к плохому коду. Каждый из нас в свое время ковырял говнокод. Я однажды правил метапоисковик ИНДУСА с переменными на индусском, в одну строчку файл. Это был ппц. С тех пор привожу как пример.
    И вот все мы, хорошие программисты, запоминаем ощущения, и ассоциируем говнокод с геммороем. И когда видим нечто подобное снова — ощущение возникает на автомате. А потом уже сознание подыскивает причину гнева — плохой язык, плохой код, молодой автор, жена не дала, и так далее.

    Желаю всем новичкам поскорее проходить стадию говнокодинга. Первое и самое главное — осознать, что никакие отмазки типа «ну работает же» не заменят признания, что ты всегда будешь в чем-то хуже лучших программистов, и что текущий код можно улучшить. И второе желаю — побольше читать правильных авторов, Макконнела, Мартина, других мудрых дядей, и применять все прочитанное на практике.

    И да, Питон — рулез, а Джанга — лучшая на свете приблуда! Руби отдыхает в сторонке (кстати ИМХО Руби — это как продолжение языка Перл — в итоге на обоих очень легко благодаря всяким штукам с приставкой мета- наговнокодить, не то что на Питоне).
    • 0
      Нда, вроде бы ничего не предвещало… годный вброс
      • +2
        Ну там наверху уже делали, чем я хуже?
        • 0
          Неа, на весь топик вбросом можно назвать только последний абзац Вашего первого поста, аналогов не нашёл. А «чем я хуже» это аргумент сами знаете из какой области)
    • +1
      Прикольно. 4 абзаца посветил рассуждениям, что не php плох, а руки у людей кривые, а в конце обосрал perl и ruby. Я конечно всё понимаю, но осадочек то остался.
  • 0
    В последнее время я начал понимать, что читаю топики и комментарии на хабре еще до их опубликования, you are not alone. Важен только результат, а способы и инструменты его реализации никого не интересуют. Наверно кроме людей, которые в коде копаются. Главное парадокс в том, что компании которые с хорошим кодом — быстро сворачиваются, а говнокодеры — быстро поднимаются, становятся лидерами в области и не плохо зарабатывают на поддержке — реалии жизни.
    • 0
      Ничего подобного. Лидеры те, кто быстрее и гибче, быстро и хорошо — не говнокод.
      • +1
        Говно-код писать быстрее и проще, это факт.
        NZeraF во многом прав — пока одни совершенствуют свой код, другие по-быстрому завоевывают ниши.
        Это, впрочем, говно-код не оправдывает и не защищает :)
        • 0
          Говнокод на то и говнокод, что в нём даже аффтар ногу сломит, поэтому это нифига не быстрее и не проще — некоторые просто по-другому не умеют.

          Ок, давайте с примерами: уверены ли Вы, что твиттер наложен? Дело в том, что можно привести в пример много лидеров, у которых с кодом *интуицивно* всё в порядке (не видел, не проверял, но это кажется естественным). А вот где примеры обратного? Принцип презумпции невиновности — до тех пор пока код не увиден, он не считается говнокодом.
  • 0
    >Данные передаются GET запросом, для просмотра этих данных вы можете установить http-сниффер например HttpAnalyzerStd.
    я для этих целей добавлял в список трекеров в торрент-клиенте свой PHP-скрипт на локалхосте и смотрел заголовки. зачем усложнять?
  • 0
    «А вот эта таблица нам нужна.»
    И длинное описание безо всяких объяснений, зачем нужны все эти столбцы.

    Очень плохо разъяснено, просто куски кода.
  • +1
    Говно пост с таким же кодом.
  • 0
    Ваш код ужасен. Не пишите так больше. Из-за таких как вы, PHP считается говноязыком.
  • 0
    ИМХО забыт копирайт. Код чужой, какого-то простого трекера.
    • 0
      функция bencode из простого трекера, остальное нет.
  • 0
    Очень похоже на 100% копипаст www.whitsoftdev.com/opentracker/ с немного расширенным переводом комментариев из кода…
  • 0
    Зачем писать свое если есть чужое. Я когда-то у себя на сайте решал задачу разадчи популярных файлов со своего сервака и писал об этом в блоге:
    soloro.ru/?p=1979
  • 0
    Как минимум, в качестве обучающего материала код очень даже годится — ознакомиться с базовыми принципами работы с p2p.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.