[BCB6] TUdpSocket, IdUdpServer - Приложение зависает...

Тема в разделе "LANGS.C", создана пользователем MuForum, 29 июл 2007.

  1. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    Доброе время суток!
    Работаю на "Borland C++ Builder 6.0".
    Задача: Сделать проверку активности приложения, через каждые 5 секунд.

    Компонент TUdpSocket - Вообще не работает, точнее ресивер не работает, а мне именно ресивер и нужен только.
    Использовал компонент IdUdpServer, но проблема заключается в том, что иногда при выключение приложения программа зависает, а иногда всё нормально. Я перепробовал 9 способов, и во всех 9 способов был один и тотже исход, то зависает программа, то всё нормально.

    P.S. -> Я пробовал делать проверку через поиску по хэндлу(заголовку), по классу хотел, но класс не виден у приложения(скрыт - использовал для обнаружения программу "Process Viewer 4.03"), пробовал ещё многими способами, но полюбому: При выключение программы, которая посылает пакеты по порту 55557(UDP), иногда программа зависает, а иногда всё нормально!

    Вот способ, который я сделал и он мне больше всего нравиться.

    Код (Text):
    1. TDateTime JStime; // Глобальная переменная.
    2. int JSUpdateWrite=0; // Глобальная переменная.
    3. int JSErrorWrite=0; // Глобальная переменная.
    4. //---------------------------------------------------------------------------
    5. #define MAXBUF2 32767 // Main.h
    6. //---------------------------------------------------------------------------
    7.  
    8. void __fastcall TForm1Main::IdUDPServer1UDPRead(TObject *Sender,
    9.       TStream *AData, TIdSocketHandle *ABinding)
    10. {
    11.   char buf[MAXBUF2];
    12.   ZeroMemory(&(buf[0]), MAXBUF2);
    13.   int bsize = IdUDPServer1->ReceiveBuffer(&(buf[0]), MAXBUF);
    14.  
    15.   buf[bsize]=0; // добавление завершающего нуля.
    16.   PacketCore2(LPBYTE(buf));
    17. }
    18. //---------------------------------------------------------------------------
    19.  
    20. void __fastcall TForm1Main::PacketCore2(LPBYTE Packet)
    21. {
    22.   int sub;
    23.   if(*(Packet)==0xC1)
    24.   {
    25.         int Head = *(Packet+2);
    26.         switch(Head)
    27.         {
    28.                 case 0x01:
    29.                         UpdateServerLoad(Packet);
    30.                         if(ServersLoaded==0)
    31.                         {
    32.                         WriteLogs2("Servers Loaded!", 0);
    33.                         ServersLoaded=1;
    34.                         }
    35.                 break;
    36.                 case 0x02:
    37.                         if(JSUpdateWrite==0)
    38.                         {
    39.                         WriteLogs2("JoinServer update complate.", 0);
    40.                         JSUpdateWrite=JSUpdateWrite+1;
    41.                         if(Timer1->Enabled!=true) Timer1->Enabled=true;
    42.                         }
    43.                         JStime=Time();
    44.                 break;
    45.         default: break;
    46.         }
    47.   }
    48. }
    49. //---------------------------------------------------------------------------
    50.  
    51. void __fastcall TForm1Main::Timer1Timer(TObject *Sender)
    52. {
    53.   TDateTime CurrentTime1;
    54.   ReplaceTime(CurrentTime1,JStime);
    55.   TDateTime CurrentTime2 = Time();
    56.   TDateTime CurrentTime4 = 0.00006;  // Это 5 секунд! (0:00:05)
    57.   TDateTime CurrentTime3 = CurrentTime2 - CurrentTime1;
    58.   WriteLogs2("JS Time: "+CurrentTime3, 0);
    59.   if(CurrentTime3 > CurrentTime4)
    60.   {
    61.     if(Edit2->Text!="Offline") Edit2->Text="Offline";
    62.     JSUpdateWrite=0;
    63.       if(JSErrorWrite==0)
    64.       {
    65.       WriteLogs2("Time Out JoinServer - Connected false.", 1);
    66.       JSErrorWrite=JSErrorWrite+1;
    67.       }
    68.     Timer1->Enabled=false;
    69.   }
    70.   else
    71.   {
    72.     if(Edit2->Text!="Online") Edit2->Text="Online";
    73.     JSErrorWrite=0;
    74.   }
    75. }
    76. //---------------------------------------------------------------------------
    P.S. -> Компилирую как "Release", а не как "Full Debug". (Project -> Options -> Compiler -> Release).

    P.S. -> Прошу людей, кто разбирается в таких делах помочь, так как я уже около недели мучаюсь и не могу выявить проблему =(
     
  2. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    MuForum
    Компонент TClientSocket\TServerSocket нормально отрабатывает, для большинства задач он самое то! Ты же не собираешься писать высконагруженный тулз, каким является апач или NginX, так что думаю на TClientSocket самое то!
     
  3. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    #2, EvilsInterrupt - Мне необходим пока компонент для работы с UDP протоколом, а не TCP/IP!

    P.S. -> Если TClientSocket\TServerSocket можно использовать и для UDP протокола, то поправьте!
     
  4. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    Сейчас постараюсь внятно и доступно всё объяснить!
    ------------------------------------------------------------------------
    Есть приложение "JoinServer.exe" (Эта не моя программа), JS посылает 2 пакета в секунду по порту 55557(UDP). JS отправляет пакет в 8 байт, вот такого формата: "\xC1\x08\x02\xF1\x00\x00\x00\x00".
    Есть другая программа ConnectServer.exe(Моя программа), CS должен принимать этот пакет по порту 55557(UDP), Обрабатывать и если заголовок этого пакета(3 байт) равен "0x02", то тогда показывать статистику и делать другие действия!

    P.S. -> Как я реализовал это: Когда приходит пакет по порту 55557(UDP), дальше этот пакет передаётся функции "PacketCore2", если 3 байт пакета строго равен "0x02", то это пакет статистики JS, в этот момент запоминается время прибытия пакета(Записывается в глобальную переменную "JStime"). Дальше каждые 5 секунд срабатывает таймер, и там уже условия: Если данное время минут время "JStime" больше 5 секунд, значит JS сейчас не доступен!


    Вопрос: В чем заключается "подвисание"?
    Ответ: Программа покрывается белым фоном и с ней не возможно работать(В Диспетчере пишется: Не отвечает).

    P.S. -> ConnectServer.exe - Это одностороннее приложение! (JoinServer.exe был написан не мной)

    Но проблема в том, что при закрытие JoinServer.exe моя программа(ConnectServer.exe) иногда подвисает(пока обратно не включить JS или вырубить процесс), а иногда всё нормально. Вот и возникает вопрос, где я допустил ошибку?!


    P.S. -> Вот свойства компонента:
    Код (Text):
    1.   IdUDPServer1->BroadcastEnable=true;
    2.   IdUDPServer1->ThreadedEvent=false;
    3.   IdUDPServer1->Tag=0;
    4.   IdUDPServer1->BufferSize=8192;
     
  5. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    #for all - Всё я свою проблему решил, она заключалась в том, что я не включил параметр "ThreadedEvent" + в косметике кода.

    Но возникла теперь другая проблема, вот сам код:
    Код (Text):
    1. void __fastcall TForm1Main::IdUDPServer1UDPRead(TObject *Sender,
    2.       TStream *AData, TIdSocketHandle *ABinding)
    3. {
    4.   char buf[MAXBUF2];
    5.   ZeroMemory(&(buf[0]), MAXBUF2);
    6.   int bsize = IdUDPServer1->ReceiveBuffer(&(buf[0]), MAXBUF);
    7.  
    8.   buf[bsize]=0; // добавление завершающего нуля.
    9.   PacketCore2(LPBYTE(buf));
    10. }
    11. //---------------------------------------------------------------------------
    12.  
    13. void __fastcall TForm1Main::PacketCore2(LPBYTE Packet)
    14. {
    15.   int sub;
    16.   if(*(Packet)==0xC1)
    17.   {
    18.         int Head = *(Packet+2);
    19.         switch(Head)
    20.         {
    21.                 case 0x01:
    22.                         UpdateServerLoad(Packet);
    23.                         if(ServersLoaded==0)
    24.                         {
    25.                         WriteLogs2("Servers Loaded!", 0);
    26.                         ServersLoaded++;
    27.                         }
    28.                 break;
    29.                 case 0x02:
    30.                         if(JSUpdateWrite==0)
    31.                         {
    32.                         WriteLogs2("JoinServer update complate.", 0);
    33.                         JSUpdateWrite++;
    34.                         if(!Timer1->Enabled) Timer1->Enabled=true;
    35.                         }
    36.                         JStime=Time();
    37.         }
    38.   }
    39. }
    40. //---------------------------------------------------------------------------
    Проблема заключается в том, что теперь какой первый пакет пришел, то только он и обрабатывается почему-то =(

    Тоесть: Если первый пакет пришел с 3 байтом "0x01", то только он и обрабатывается, а пакет с 3 байтом "0x02" почему-то не обрабатывается, тоесть тупо пропускается =(