На главную Наши проекты:
Журнал   ·   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_
Страницы: (4) 1 2 [3] 4  все  ( Перейти к последнему сообщению )  
> Проверка существования подключения к Socket Server со стороны клиента
    Цитата Fr0sT @
    Ага, особенно в realtime приложениях :lool:

    Особенно в них. :D
      Цитата apprentice @
      Отправляю служебные коды дивайся поэтому выглядят чутка дико.

      Кстати - неправильно отправляешь. Смотри:
      Цитата apprentice @
      ExpandedWrap disabled
        output.Socket.SendBuf(BufS,14)

      При таком раскладе у тебя передастся сам указатель на буфер данных (4 байта) и соседствующий с ним код в пределах 10 байт. Но это, к сожалению не данные, которые ты так аккуратно, байт за байтом загоняешь в массив. Поэтому необходимо делать так:
      ExpandedWrap disabled
        output.Socket.SendBuf(BufS[1],14)
      Разумеешь? :D
      Сообщение отредактировано: medved_68 -
        Цитата medved_68 @
        Кстати - неправильно отправляешь

        У него статический массив, так что всё ОК
          С массивом все норм дивайс принимает командные коды. А вот где выставляется тайм аут для обработчика ошибок так и не нашел. Единственная функция для проверки готовности сокетов которую я нарыл это function select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): LongInt; но она вот не сильно скорее всего захочет сотрудничать с TClientSocket. Так что если Вы знаете как установить тайм-ауту для обработки ошибок TClientSocket буду очень благодарен. Просто проводя тест с таймером и sendBuf сейчас вообще не вызывает событие он OnError когда я физически отключаю питание серверу

          ExpandedWrap disabled
            unit Unit2;
             
            interface
            uses
              Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
              Dialogs, ScktComp, StdCtrls, WinSock, Sockets, ExtCtrls;
             
            Type
              TKpp=class
              private
                TcpClient1: TTcpClient;
                input: TClientSocket;
                output: TClientSocket;
                controller: TClientSocket;
                timer:TTimer;
             
             
               // procedure outputRead(Sender: TObject; Socket: TCustomWinSocket);
               // procedure controllerRead(Sender: TObject; Socket: TCustomWinSocket);
             
              public
                name,sin,s1in,Erro:string;
                procedure Err(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
                procedure inputcon(Sender: TObject; Socket: TCustomWinSocket);
                procedure Read(Sender: TObject; Socket: TCustomWinSocket);
                function idtransfer(id:string):string;
                procedure setIPin(s:string);
                procedure setPortin(s:string);
                procedure InActivate(bool:boolean);
                procedure setIPout(s:string);
                procedure setPortout(s:string);
                procedure outActivate(bool:boolean);
                procedure setIPcon(s:string);
                procedure setPortcon(s:string);
                procedure conActivate(bool:boolean);
                procedure CheckIP;
                procedure clienttype(SokName:string; SokType:integer);
                procedure ding(Sender: TObject);
             
             
                constructor create;
                destructor destroy;
             
            end;
            implementation
              uses unit1, Thread;
            { TKpp }
             
            procedure TKpp.conActivate(bool: boolean);
            begin
              controller.Active:=bool;
            end;
             
            constructor TKpp.create;
            begin
              timer:=tTimer.Create(nil);
              timer.Interval:=2000;
              timer.OnTimer:=Ding;
              timer.Enabled:=true;
              TcpClient1:=TTcpClient.create(nil);
              input:=TClientSocket.Create(nil);
              input.ClientType:=ctBlocking;
              //input.OnConnect:=inputcon;
              //input.OnRead:=Read;
              output:=TClientSocket.Create(nil);
              output.OnRead:=Read;
              output.OnError:=Err;
              //output.OnConnecting:=tesConn;
             
             
              controller:=TClientSocket.Create(nil);
              controller.OnRead:=Read;
            end;
             
            destructor TKpp.destroy;
            begin
              input.Destroy;
              output.Destroy;
              controller.Destroy;
            end;
             
             
            function TKpp.idtransfer(id: string): string;
            begin
               id:=id;
            end;
             
            procedure TKpp.InActivate(bool:boolean);
            begin
              input.Active:=bool;
            end;
             
            procedure TKpp.Read(Sender: TObject; Socket: TCustomWinSocket);
            var buf:byte;
            begin
              if Socket.ReceiveLength<6 then
              begin
                Socket.ReceiveBuf(buf,1);
                sin:=sin+inttostr(buf);
                s1in:=s1in+inttohex(buf,2);
              end;
              if Socket.ReceiveLength=6 then
              begin
                  Socket.ReceiveBuf(buf,1);
                  sin:='';
                  sin:=inttostr(buf);
                  s1in:=inttohex(buf,2);
              end;
              if Socket.ReceiveLength=0 then
                Begin
                //idtransfer(sin);
                //idtransfer(input.Socket.ReceiveText);
                 form1.id:=sin;
                 if sender=input then
                    Begin
                     showmessage(Name+' âîøîë'+'='+sin);
                    end;
                 if sender=output then
                    Begin
                      showmessage(Name+' âûøåë'+'='+sin);
                      form1.id:=sin;
                      form1.Label2.Caption:=Name+' âûøåë'+'='+sin;
             
                    end;
                  if sender=controller then
                    Begin
                      showmessage('Êîíòðîëëåð');
                    end;
                end;
             
            end;
             
            procedure TKpp.outActivate(bool: boolean);
            begin
              output.Active:=bool;
            end;
             
            procedure TKpp.setIPcon(s: string);
            begin
              controller.Address:=s;
            end;
             
            procedure TKpp.setIPin(s: string);
            begin
              input.Address:=s;
            end;
             
            procedure TKpp.setIPout(s: string);
            begin
              output.Address:=s;
            end;
             
            procedure TKpp.setPortcon(s: string);
            begin
              controller.Port:=strtoint(s);
            end;
             
            procedure TKpp.setPortin(s: string);
            begin
              input.Port:=strtoint(s);
            end;
             
            procedure TKpp.setPortout(s: string);
            begin
              output.Port:=strtoint(s);
            end;
             
             
             
            procedure TKpp.inputcon(Sender: TObject; Socket: TCustomWinSocket);
            var s:TWinSocketStream;
                buf1:array[1..6] of byte;
                st:string;
                i:integer;
            begin
            i:=0;
            s:=TWinSocketStream.Create(input.Socket,60000);
            while not s.WaitForData(100) do
              Begin
                Application.ProcessMessages;
             
              end;
                for i:=1 to s.Read(buf1,6) do
                  begin
                    st:=st+inttostr(buf1[i]);
                  end;
             
            showmessage(st);
            end;
             
            procedure Tkpp.Err(Sender: TObject;
              Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
              var ErrorCode: Integer);
            begin
             
              //errorcode:=0;
              form1.Label1.Caption:='ошибка связи';
              output.Active:=true;
             
            end;
             
            procedure TKpp.clienttype(SokName:string; SokType: integer);
            begin
            if (SokName='output')and(SokType=1) then
              output.Socket.ClientType:=ctBlocking;
            if (SokName='input')and(SokType=1) then
              input.Socket.ClientType:=ctBlocking;
            if (SokName='controller')and(SokType=1) then
              controller.Socket.ClientType:=ctBlocking;
             
            end;
             
            procedure TKpp.ding(Sender: TObject);
              var bufs:array[1..14] of byte;
             
            begin
             
             
              bufS[1]:=30;
              bufS[2]:=5;
              bufS[3]:=5;
              bufS[4]:=0;
              bufS[5]:=0;
              bufS[6]:=0;
              bufS[7]:=0;
              bufS[8]:=0;
              bufS[9]:=0;
              bufS[10]:=0;
              bufS[11]:=0;
              bufS[12]:=0;
              bufS[13]:=0;
              bufS[14]:=0;
              output.Socket.SendBuf(BufS[1],14);
            end;
             
            end.


          Добавлено
          в коде вместо этого output.Socket.SendBuf(BufS[1],14) вот это output.Socket.SendBuf(BufS,14)
            Для таймаута есть несколько способов:
            1) Вызывать select с нужным таймаутом - будет блокировать выполнение до истечения таймаута, если сокет не готов
            2) В цикле вызывать select с небольшим таймаутом и наращивать счетчик до нужного значения, добавить досрочный выход / обработку сообщений по вкусу
            3) setsockopt + SO_RCVTIMEO/SO_SNDTIMEO

            Добавлено
            Цитата apprentice @
            но она вот не сильно скорее всего захочет сотрудничать с TClientSocket


            TClientSocket - просто обертка над WinAPI, так что бери его Handle и делай все, что захочется
              {$EXTERNALSYM SO_SNDTIMEO}
              SO_SNDTIMEO = $1005; насколько я понимаю это время в мили секундах по умолчанию.

              ExpandedWrap disabled
                procedure TKpp.ding(Sender: TObject);
                  var bufs:array[1..14] of byte;
                    s:TSocket;
                    SocketSet: TFDSet;
                    Timeout: TTimeVal;
                 
                begin
                  s:=output.Socket.Handle;
                  FD_ZERO(SocketSet);
                 FD_SET(s, SocketSet);
                 Timeout.tv_sec := 5;
                 Timeout.tv_usec := 0;
                if select(0, @SocketSet, nil, nil, @Timeout) = SOCKET_ERROR then
                 begin
                  showmessage('Îøèáêà ïðè ïðîâåðêå ãîòîâíîñòè ñîêåòà:  '+ inttostr(WSAGetLastError));
                  Exit;
                 end;


              Добавлено
              а этот код если я вас правильно понял возвращает ошибку сокет не существует 10038

              Добавлено
              при этом сокет работает

              Добавлено
              ExpandedWrap disabled
                getsockopt(S, SOL_SOCKET, SO_SNDTIMEO, @Val, Len);
                 showmessage(inttostr(val));


              Дало значение 0
                Все верно, по дефолту это значение и есть 0. setsockopt для изменения опций.
                  Цитата apprentice @
                  Просто проводя тест с таймером и sendBuf сейчас вообще не вызывает событие он OnError когда я физически отключаю питание серверу

                  Так и должно быть. Ты попробуй сделать вот такую последовательность:
                  1. Отключить сервер от сети при подключенном к нему клиенте.
                  2. После этого попробовать отправить что-нибудь на сервер.
                  В этом случае у тебя должно произойти событие ошибки сокета. :D
                    Цитата medved_68 @
                    Цитата apprentice @
                    Просто проводя тест с таймером и sendBuf сейчас вообще не вызывает событие он OnError когда я физически отключаю питание серверу

                    Так и должно быть. Ты попробуй сделать вот такую последовательность:
                    1. Отключить сервер от сети при подключенном к нему клиенте.
                    2. После этого попробовать отправить что-нибудь на сервер.
                    В этом случае у тебя должно произойти событие ошибки сокета. :D

                    я с Вами абсолютно согласен. Но вот проблема в том что сокет с нами не согласен

                    Добавлено
                    Может я не правильно понимаю событие ошибка. Вы имеете в виду возбуждение OnError? Если да то его не происходит.
                      Кто подскажет почему при включенном сокете когда сокет сервер присылает и я отправляю сообщения ему этот код

                      ExpandedWrap disabled
                        procedure TKpp.ding(Sender: TObject);
                          var bufs:array[1..14] of byte;
                            s:TSocket;
                            SocketSet: TFDSet;
                         // Òàéì-àóò äëÿ ôóíêöèè select
                            Timeout: TTimeVal;
                            Len,Val:integer;
                        begin
                          //showmessage(inttostr(output.Socket.Handle));
                          s:=output.Socket.Handle;
                          FD_ZERO(SocketSet);
                         FD_SET(s, SocketSet);
                         Timeout.tv_sec := 0;
                         Timeout.tv_usec := 900;
                         Len := SizeOf(Integer);
                         Val:=5;
                          if select(0, @SocketSet, nil, nil, @Timeout)= SOCKET_ERROR then
                            begin
                              showmessage('ошибка ' +inttostr(WSAGetLastError));
                         
                            exit;
                            end;


                      возвращает ошибка 10038 - ?

                      может ли это быть из-за того что сокет в не блокируемом режиме?
                        Цитата medved_68 @
                        Цитата apprentice @
                        Просто проводя тест с таймером и sendBuf сейчас вообще не вызывает событие он OnError когда я физически отключаю питание серверу

                        Так и должно быть. Ты попробуй сделать вот такую последовательность:
                        1. Отключить сервер от сети при подключенном к нему клиенте.
                        2. После этого попробовать отправить что-нибудь на сервер.
                        В этом случае у тебя должно произойти событие ошибки сокета. :D

                        самое смешное что событие возбуждается после того как я снова включаю дивайс. Тоисть на сколько я понимаю пока дивайс не ответ что произошла ошибка клиент в ступоре.
                          Цитата apprentice @
                          Вы имеете в виду возбуждение OnError? Если да то его не происходит.

                          Т.е при отключенном девайсе (но коннект до этого был установлен) при попытке записи в сокет не возбуждается ошибка, так? А что возвращает операция записи:
                          Цитата medved_68 @
                          2. После этого попробовать отправить что-нибудь на сервер.

                          ???:huh:
                            В том то и дело в коде видно что в таймере есть отправка. Но она ничего не возвращает пока я не включу сервак обратно. Как только включаю снова сервер ошибка 10056 по моему вылетает. Но почему при выключенном сервере нет никаких событий? С чем это связано? Тока не надо говорить с кривыми руками :rolleyes: я их как раз ровнять пытаюсь :D
                              Цитата apprentice @
                              В том то и дело в коде видно что в таймере есть отправка.

                              Ты код отправки при выключенном сервере показывай. А потом будем рассуждать, почему "лыжи не едут". :D
                                Цитата medved_68 @
                                Цитата apprentice @
                                В том то и дело в коде видно что в таймере есть отправка.

                                Ты код отправки при выключенном сервере показывай. А потом будем рассуждать, почему "лыжи не едут". :D

                                ну как бы вот код в таймере
                                ExpandedWrap disabled
                                  procedure TKpp.ding(Sender: TObject);
                                    var bufs:array[1..14] of byte;
                                      s:TSocket;
                                      SocketSet: TFDSet;
                                   // Òàéì-àóò äëÿ ôóíêöèè select
                                      Timeout: TTimeVal;
                                      Len,Val:integer;
                                  begin
                                   
                                    //showmessage(inttostr(output.Socket.Handle));
                                   s:=output.Socket.Handle;
                                   FD_ZERO(SocketSet);
                                   FD_SET(s, SocketSet);
                                   Timeout.tv_sec := 0;
                                   Timeout.tv_usec := 50;
                                   Len := SizeOf(Integer);
                                   Val:=50;
                                   setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, @Val, Len);
                                  // getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, @Val, Len);
                                   getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, @Val, Len);
                                   getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, @Val, Len);
                                   //showmessage(inttostr(val));
                                   
                                  //if WSAAsyncSelect(S, form1.Handle, WM_USER+1, FD_READ or FD_WRITE)= SOCKET_ERROR then
                                   
                                    if select(0, @SocketSet, nil, nil, @Timeout)= SOCKET_ERROR then
                                      begin
                                        showmessage('îøèáêà ' +inttostr(WSAGetLastError));
                                   
                                      exit;
                                      end;
                                   
                                   
                                    bufS[1]:=30;
                                    bufS[2]:=5;
                                    bufS[3]:=5;
                                    bufS[4]:=0;
                                    bufS[5]:=0;
                                    bufS[6]:=0;
                                    bufS[7]:=0;
                                    bufS[8]:=0;
                                    bufS[9]:=0;
                                    bufS[10]:=0;
                                    bufS[11]:=0;
                                    bufS[12]:=0;
                                    bufS[13]:=0;
                                    bufS[14]:=0;
                                    output.Socket.SendBuf(BufS,14);
                                   
                                   
                                  end;


                                Добавлено
                                даже так будет правельнее
                                ExpandedWrap disabled
                                  procedure TKpp.ding(Sender: TObject);
                                    var bufs:array[1..14] of byte;
                                      s:TSocket;
                                      SocketSet: TFDSet;
                                   // Òàéì-àóò äëÿ ôóíêöèè select
                                      Timeout: TTimeVal;
                                      Len,Val:integer;
                                  begin
                                   
                                    //showmessage(inttostr(output.Socket.Handle));
                                   {
                                  s:=output.Socket.Handle;
                                   FD_ZERO(SocketSet);
                                   FD_SET(s, SocketSet);
                                   Timeout.tv_sec := 0;
                                   Timeout.tv_usec := 50;
                                   Len := SizeOf(Integer);
                                   Val:=50;
                                   setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, @Val, Len);
                                  // getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, @Val, Len);
                                   getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, @Val, Len);
                                   getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, @Val, Len);
                                   //showmessage(inttostr(val));
                                   
                                  //if WSAAsyncSelect(S, form1.Handle, WM_USER+1, FD_READ or FD_WRITE)= SOCKET_ERROR then
                                   
                                    if select(0, @SocketSet, nil, nil, @Timeout)= SOCKET_ERROR then
                                      begin
                                        showmessage('îøèáêà ' +inttostr(WSAGetLastError));
                                   
                                      exit;
                                      end;
                                  }
                                   
                                   
                                    bufS[1]:=30;
                                    bufS[2]:=5;
                                    bufS[3]:=5;
                                    bufS[4]:=0;
                                    bufS[5]:=0;
                                    bufS[6]:=0;
                                    bufS[7]:=0;
                                    bufS[8]:=0;
                                    bufS[9]:=0;
                                    bufS[10]:=0;
                                    bufS[11]:=0;
                                    bufS[12]:=0;
                                    bufS[13]:=0;
                                    bufS[14]:=0;
                                    output.Socket.SendBuf(BufS,14);
                                   
                                   
                                  end;
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (4) 1 2 [3] 4  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.1019 ]   [ 15 queries used ]   [ Generated: 24.10.26, 03:05 GMT ]