На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

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

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
  
> Слушаем порт , определение активности на определенном порту
    Народ, тут у меня появилась необходимость определять события, когда кто-нить обращается к определенному порту моего компа.
    Так вот, как енто сделать?
    Можна конечно просто взять TServerSocket и через его OnAccept определять момент активности, но при этом если какя-то прога уже работает с этим портом - то этот самый TServerSocket ругается при своей активации, типа "разрешено только одно использование адреса сокета"
    Как с этим бороться, а еще лучше может есть другие средства по "прослушиванию" портов.
    Будет интересно узнать способы реализации сабжа.
      Имхо, только на более низком уровне.
        ZEE
        По-моему в FAQ по СИ я уже такое видел.
        Там сокет вводился в прослушивающийся режим и выводил инфу в файл, этакий снифер.
          Да нашел там образцы снифферов - один вроде как более-менее понятный - от него начал отталкиаться в итоге получилась такая штука (код чуть ниже), но не могу понять что не так - в общем посмотрите и посоветуйте что исправить или заменить...
          uses ..., WinSock, ScktComp;
          ...
          const
            MAX_PACKET_SIZE=$10000;
          var
            WSAData:TWSAdata;                 // Инициализация WinSock
            s:TSocket;                        // Cлущающий сокет
            LocalName: array[0..255] of Char; // Имя хоста (компьютера)
            phe:PHostEnt;                     // Информация о хосте
            sa:TSockAddrIn;                   // Адрес хоста
            flag:Longint = 0;                 // Флаг PROMISC Вкл/выкл
            Buffer:array[0..MAX_PACKET_SIZE]of char; // Буфер для приёма данных
          ...
          procedure TForm1.FormCreate(Sender: TObject);
          begin
            WSAStartup($0202, WSAData);
            s:=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
            if s=INVALID_SOCKET then Memo1.Lines.Add('socket error');
            GetHostName(LocalName, SizeOf(LocalName));
            phe:=GetHostByName(LocalName);
            ZeroMemory(@sa,SizeOf(sa));
            sa.sin_family:=AF_INET;
            sa.sin_port:=htons(0);//если ставить конкретный порт то bind() потом не проходит :(
            sa.sin_addr.s_addr:=INADDR_ANY;
            if bind(s,sa,SizeOf(sa))=SOCKET_ERROR then Memo1.Lines.Add('bind error');
            if ioctlsocket(s,FIONBIO,flag)=SOCKET_ERROR then Memo1.Lines.Add('ioctlsocket error');
            Timer1.Enabled:=true;
          end;

          procedure TForm1.Timer1Timer(Sender: TObject);
          var rescode:integer;
          begin
            if ioctlsocket(s,FIONREAD,flag)=SOCKET_ERROR then Memo1.Lines.Add('ioctlsocket error');
            rescode:=recv(s, Buffer, SizeOf(Buffer), 0);
            if rescode <> SOCKET_ERROR then
              Memo1.Lines.Add(Buffer);
          end;

          procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
          begin
            Timer1.Enabled:=false;
            closesocket(s);
            WSACleanup;
          end;

          конешна по-хорошему надо было бы не на таймер вешать, а события обрабатывать, но я с ними вобще что-т не могу разобраться...
          и на счет sa.sin_port:=htons(0); - как после bind() прицепить сокету нужный порт или как сразу указать нужный, чтоб bind() срабатывал нормально?...
          зы: как вы наверно заметили все сообщения и (возможные) перехваченные пакеты заносятся в Memo1 (это так для информации)
            Цитата
            ZEE, 22.12.03, 15:31
            procedure TForm1.Timer1Timer(Sender: TObject);
            var rescode:integer;
            begin
              if ioctlsocket(s,FIONREAD,flag)=SOCKET_ERROR then Memo1.Lines.Add('ioctlsocket error');
              rescode:=recv(s, Buffer, SizeOf(Buffer), 0);
              if rescode <> SOCKET_ERROR then
                Memo1.Lines.Add(Buffer);
            end;

            Поскольку в recv можно "провалиться" на долго (больше чем величена таймера Timer1), надо защитится от повторного входа. Да и если ошибка на сокете, то наверное вызывать recv не стоит. Например так:
            procedure TForm1.Timer1Timer(Sender: TObject);
            var rescode:integer;
            begin
              Timer1.Active := False;
              try
                if ioctlsocket(s,FIONREAD,flag)=SOCKET_ERROR then
                  Memo1.Lines.Add('ioctlsocket error')
                else begin
                  rescode:=recv(s, Buffer, SizeOf(Buffer), 0);
                  if rescode <> SOCKET_ERROR then
                    Memo1.Lines.Add(Buffer);
                end;
              finally
                Timer1.Active := True;
              end;
            end;

            Но в принципе, надо-бы еще определять сколько данных уже имеется в буфере WinSock и лиш только это кол-во запрашивать в recv. Иначе, провиснешь в нем до получения SizeOf(Buffer) байтов - а это может быть даже навсегда smile.gif.
              >Петрович - да совет хороший (разв што не Timer1.Active, а Timer1.Enabled)
              но все-одно остается вопрос
              что делать с sa.sin_port:=htons(0); - нужный порт туда ставить или как-то потом его куда-нить присобачивать (и как) ???
              пытаюсь делать то же что и в ScktComp.pas но ни х не получаеца (всмысле там надо конкретно порт указывать сразу - а как я говорил при этом бинд ругается и как я понял без этого бинда низя)
              вобщем F1 plz mellow.gif
              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
              0 пользователей:


              Рейтинг@Mail.ru
              [ Script execution time: 0,0222 ]   [ 16 queries used ]   [ Generated: 1.05.24, 09:46 GMT ]