Конференция "Сети" » ClientSocket нет события onRead [D7, WinXP]
 
  • VFaust © (26.10.10 10:46) [0]
    Что имеется:
    1. Контроллер (PLC) c Ethernet его IP=192.168.0.20 (порт для подключения 102);
    2. Компьютер (PC) мой IP=192.168.0.12

    Что требуется:
    1. Подключиться к порту
    2. Периодически отсылать посылки байтов

    Что делаю:
    1. На форму ClientSocket поставил параметры:
    Address: 192.168.0.20
    ClientType: ctNonBlocking
    Port: 102
    2. На кнопку отсылаю ClientSocket1.Socket.SendText(#00);
    3. Жду событие onRead

    Что не получается:
    1. Не происходит события onRead...
    2. Через несколько посылок Disconnect...

    Аргумент:
    смотрю пакеты CommView`ом, пакеты видны...
  • Slym © (26.10.10 12:28) [1]
    VFaust ©   (26.10.10 10:46)
    Новичку проще в Blocking режиме...
    procedure TForm1.Button1Click(Sender: TObject);
    var
     CSock:TClientSocket;
     CStream:TWinSocketStream;
     Buf:array[byte] of char;
     Readed:integer;
    begin
     CSock:=TClientSocket.Create(nil);
     try
       CSock.ClientType:=ctBlocking;
       CSock.Address:='192.168.0.20';
       CSock.Port:=102;
       CSock.Active:=true;
       CStream:=TWinSocketStream.Create(CSock.Socket,10000);
       try
         while CSock.Active do
         begin
           CSock.Socket.SendText(#00);
           if not CStream.WaitForData(CStream.TimeOut) then Break;
           Readed:=CStream.Read(Buf,SizeOf(Buf));

         end;
       finally
         CStream.Free;
       end;
     finally
       CSock.Free;
     end;
    end;

  • VFaust © (26.10.10 13:52) [2]

    > Slym ©   (26.10.10 12:28)
    >
    > Новичку проще в Blocking режиме...
    >

    Пробовал..., приложение ждет некоторое время..., но посылки не видит..
    смотрю пакеты CommView`ом, пакеты видны...

    передавал: #00
    должен принять: #00 #00 #00 #00 #00 #00

    P.S. пробовал делать мини-Чат, всё работает...
    P.P.S. делал анологичное приложение, всё работает, но там был другой порт и PLC...

    может все дело в адресе порта?
  • DVM © (26.10.10 17:39) [3]

    > VFaust ©   (26.10.10 13:52) [2]

    зачем слать как текст то, что не является текстом.
  • VFaust © (26.10.10 19:35) [4]
    А зачем мне тест отсылать как массив байтов, если я массив могу отослать как строку...
    P.S. Суть дело не меняет...
  • Slym © (26.10.10 19:49) [5]

    > Пробовал..., приложение ждет некоторое время..., но посылки
    > не видит..
    > смотрю пакеты CommView`ом, пакеты видны...

    Не может быть. Если чтото их видит, а приложение  их не recv'ит это хрень полная...
    в моем коде чему равно Readed?
  • Сергей М. © (26.10.10 20:44) [6]

    > VFaust


    Я надеюсь ты не настолько бестолков чтобы вызывать SendЧегоТоТам раньше факта возбуждения OnWrite или хотя бы OnConnect ?

    Только не говори "а зачем" - зачморим и отправим в "Начинающие")
  • VFaust © (26.10.10 22:01) [7]
    Жму button1, включаем ClientSocket1.Active := true;
    Появляется событие onConnect
    Появляется событие onWrite
    Жму button2, посылаем ClientSocket1.Socket.SendText(#00);
    (вижу пакет передан через CommView)
    (почти тут же вижу ответный пакет через CommView)
    но событие onRead не выполняется
    после дальнейших нажиманий на button2 (всего 4 раза)
    Появляется событие DisConnect
  • VFaust © (26.10.10 22:10) [8]

    > Slym ©   (26.10.10 19:49) [5]
    >
    >
    > > Пробовал..., приложение ждет некоторое время..., но посылки
    > > не видит..
    > > смотрю пакеты CommView`ом, пакеты видны...
    >
    > Не может быть. Если чтото их видит, а приложение  их не
    > recv'ит это хрень полная...
    > в моем коде чему равно Readed?


    Я вас прекрасно понимаю..., но чего нет, того нет...
    Пробовал на другом компе запускать..., безрезультатно...
    Выключал все firewall`ы, касперских..., безрезультатно...
  • Сергей М. © (26.10.10 22:15) [9]
    если обработчик онрид не получает управление, значит он не назначен соответствующему свойству-событию

    иного объяснения этому "феномену" я не вижу
  • VFaust © (26.10.10 22:26) [10]

    > Сергей М. ©   (26.10.10 22:15) [9]
    >
    > если обработчик онрид не получает управление, значит он
    > не назначен соответствующему свойству-событию

    Это чья проблема моей криворукости или Delphi...?
  • Сергей М. © (26.10.10 22:39) [11]

    > VFaust ©   (26.10.10 22:26) [10]


    У меня пока нет повода пенять на Delphi)
  • VFaust © (26.10.10 23:12) [12]

    > У меня пока нет повода пенять на Delphi)

    :D
    Только что заметил маленький нюанс...
    При расшифровке пакета ComView в пакете подсвечивает части [Ethernet II], [IP], [TCP]...
    После области TCP я наблюдаю свои данные...!!!!, но в расшифровке эти данные не значатся..., а параметр TCP.Data length = 0...!!!
  • VFaust © (26.10.10 23:43) [13]
    Покопал еще...,

    во всех исходящих пакетах
    IP -> Flags -> Don't fragment bit: 1 - Don't fragment

    а во входящих пакетах
    IP -> Flags -> Don't fragment bit: 0 - May fragment
  • sniknik © (27.10.10 00:27) [14]
    > P.S. Суть дело не меняет...
    а что мы знаем о строках? pchar например. и есть ли в виндовс дельфийские string...

    p.s. очень даже меняет.
  • sniknik © (27.10.10 00:30) [15]
    > а параметр TCP.Data length = 0...!!!
    логично черт побери, если ты как текст посылаешь то, что здесь показываешь.
  • VFaust © (27.10.10 11:54) [16]
    Проблема не в отправлении, а в приеме...

    Фото пакета который я отсылаю
    [IMG]http://www.imghost.in/images/65xjap5vez0amb51zvhr.gif[/IMG]

    Фото пакета, который я не могу получить
    [IMG]http://www.imghost.in/images/veicziy6uu3fbgssl54y.gif[/IMG]

    Красным выделены различия, как мне кажется из-за которых я не вижу пакета...
    Зеленым выделены данные...
  • Сергей М. © (27.10.10 12:24) [17]
    ну если PSH не взведен во входящем пакете, то неудивительно что 5 вошедших байт висят в буфере приема и не отдаются приложению

    попробуй сразу после коннекта отключить буферизацию вх.потока установкой в ноль опции SO_RCVBUF клиентского гнезда
  • VFaust © (27.10.10 14:18) [18]

    > отключить буферизацию вх.потока установкой в ноль опции
    > SO_RCVBUF клиентского гнезда

    Я то понимаю что от меня требуется, но закодить такое сразу немогу :(...
    Курю интернет и ООП...
  • sniknik © (27.10.10 15:59) [19]
    > Проблема не в отправлении, а в приеме...
    т.е. то что при формировании пакета на оправлении компоненты ставят длину данных = 0 (что совершенно правильно с точки зрения строк), пофиг? а вот то, что при приеме они читают 0 байт это уже считается проблемой... причем не связанная с причиной.

    шутить изволите?
  • Сергей М. © (27.10.10 16:27) [20]

    > закодить такое сразу немогу


    А если чуть поднапрячь извилины и поискать в гугле готовый ответ на этот вопрос ?
  • Вариант (28.10.10 07:35) [21]

    > sniknik ©   (27.10.10 15:59) [19]
    > т.е. то что при формировании пакета на оправлении компоненты
    > ставят длину данных = 0 (что совершенно правильно с точки
    > зрения строк), пофиг?


    В Дельфи 6(подозреваю что и в  7) TClientSocket так не делает. Кстати как и строки в дельфи (ибо строки тут первичное), по крайней мере для версий Дельфи 5 и 6. Строки в дельфи бывает довольно удобно использовать как динамический массив.... Чего кстати не было в с++ билдере, насколько помню.
  • sniknik © (28.10.10 08:07) [22]
    > В Дельфи 6(подозреваю что и в  7) TClientSocket так не делает.
    я это не придумал а взял отсюда

    VFaust ©   (26.10.10 23:12) [12]
    > После области TCP я наблюдаю свои данные...!!!!, но в расшифровке эти данные не значатся..., а параметр TCP.Data length = 0...!!!

    т.что просто подозрений маловато.

    > Строки в дельфи бывает довольно удобно использовать как динамический массив....
    с этим никто и не спорит... удобно. но передавать этот динамический массив в виндовые функции через pchar очевидно не стоит. т.к.
    >> P.S. Суть дело не меняет...
    > а что мы знаем о строках? pchar например. и есть ли в виндовс дельфийские string...
    обработка строки/расчет длинны пакета без учета (откуда ему там знать?) дельфевских "маджик" типов как будет происходить?

    + еще одно
    > P.S. пробовал делать мини-Чат, всё работает...
    в чем отличие того что вбивается человеком в чате от показанного здесь?

    p.s. все же прямо тут, как 2 + 2 сложить...
  • sniknik © (28.10.10 09:24) [23]
    хорошая статья, о том почему нужно знать как что то работает, а не просто использовать
    http://russian.joelonsoftware.com/Articles/LeakyAbstractions.html
  • Вариант (28.10.10 09:37) [24]

    > Вариант   (28.10.10 07:35) [21]

    Уточню - говоря о строках -я говорил об AnsiString


    > sniknik ©   (28.10.10 08:07) [22]
    > > В Дельфи 6(подозреваю что и в  7) TClientSocket так не
    > делает.
    > я это не придумал а взял отсюда



    Если я правильно понял, то твое


    > т.е. то что при формировании пакета на оправлении компоненты
    > ставят длину данных = 0
    >


    ты о  


    > ClientSocket нет события onRead [D7, WinXP]
    >
    > VFaust ©   (26.10.10 10:46)
    > 2. На кнопку отсылаю ClientSocket1.Socket.SendText(#00);
    >


    Если так, то в ScktComp


    > function TCustomWinSocket.SendText(const s: string): Integer;
    >
    > begin
    >   Result := SendBuf(Pointer(S)^, Length(S));
    > end;


    где размер пакета будет определяться  Length(S)  и для случая #00 будет = 1

    Если я понял неправильно, то просто я не увидел тогда, о чем был пост 19.

    PS:
    Возможно автор поста хотел послать не один байт 0, а два - тогда должен был сделать #0#0, а не #00 -но это мое гадание на кофейной гуще. Хотя я согласен, что в общем для посылки двоичного контента удобнее и логично использовать SendBuf.  Хоть SendText и может упростить это, но в данном случае может привести к ошибке или разночтению....
  • VFaust © (28.10.10 09:56) [25]
    Я отсылаю один байт #00 в порт, в TCP/IP пакете прописывается длинна данных равная 1 (на скрине видно)...
    Когда ко мне приходит пакет с данными #00 #00 #00 #00 #00 #00 (6 байт), в TCP/IP пакете длинна данных указана 0 (на скрине видно)...

    Исходящие пакеты формирую я, к ним нареканий никаких...
    Входящие пакеты формирует контроллер фирмы SIEMENS по своей, недоступной мне схеме и логике...
  • Вариант (28.10.10 10:20) [26]

    > VFaust ©   (28.10.10 09:56) [25]

    К сожалению не могу сказать причину не получения пакета. Если в коде все верно - проблема в работе или настройке контроллера.
     Я не знаю этих контроллеров, с которыми ты работаешь, возможно он работает по UDP на отправку нужных тебе данных, возможно необходима какая-то конфигурация - это опять таки гадание с моей стороны. Помочь может или тот, кто уже работал с такими устройствами или чтение документации или FAQ  по твоим контроллерам.
  • VFaust © (28.10.10 10:26) [27]

    > Вариант   (28.10.10 10:20) [26]

    Я не прошу разбираться с ошибками контроллера, я хочу принимать пакеты с данными, если длинна указана равная 0..., ведь CommView их принимает...
  • Вариант (28.10.10 10:49) [28]

    > VFaust ©   (28.10.10 10:26) [27]

    Если данные для тебя есть в буфере, то способ
    указан в
    > Сергей М. ©   (27.10.10 12:24) [17]

    Моей квалификации и знаний работы в сети не хватает, что бы оценить верен этот пост(способ) или нет. Мне кажется, что это не поможет - но кажется. А когда кажется, то надо проверять, а вот как это проверить - я тебе могу подсказать - тебе надо использовать функцию setsockopt - посмотри в MSDN или в хелпе дельфи по Windows SDK (для гугла ключевые слова setsockopt, SOL_SOCKET, SO_RCVBUF).
  • Сергей М. © (28.10.10 11:01) [29]
    Ну для отпетых извращенцев есть еще способ  - cотворить файрвол и в интересующих пакетах менять PSH c 0 на 1

    )
  • sniknik © (28.10.10 11:14) [30]
    > а два - тогда должен был сделать #0#0, а не #00 -но это мое гадание на кофейной гуще.
    это ламеризм, а не гадание

    вот

    var
     s: string;
    begin
     s:= 'какая то '#00'строка...';
     ShowMessage(Copy(s, 1, 9)+Copy(s, 11, 9)); //данные есть, можно убедится
     ShowMessage(s);                            //а вот так?
     ShowMessage(IntToStr(Length(PChar(s))));   //а что думаеш покажет это?
    end;



    поставь не #00, а #0#0. помогло?
  • Вариант (28.10.10 11:17) [31]

    > Сергей М. ©   (28.10.10 11:01) [29]

    Да можно извратиться и сниффером читать. Только это извращение как ты и сказал, так как порядок получения пакетов уже будет не гарантирован. Возможно все получим как надо и правильно, а может как "PSH" на душу положит. Мне кажется проблема в работе с контроллером, опять таки если в коде  для ClientSocket все верно.
  • sniknik © (28.10.10 11:20) [32]
    > Возможно автор поста хотел послать не один байт 0, а два - тогда должен был сделать #0#0, а не #00
    а, дошло... сорри
    имеешь в виду, что
    > передавал: #00
    > должен принять: #00 #00 #00 #00 #00 #00
    передавал он типа, #000000000000, а ожидает #00#00#00#00#00#00
  • Вариант (28.10.10 11:29) [33]

    > sniknik ©   (28.10.10 11:14) [30]


    > гадание на кофейной гуще

    Это относилось к тому, сколько байт хотел отправить автор поста, ибо как я писал #00 - у меня например сперва вызвал именно такую ассоциацию, что хотел два байта, но забыл #.

    Ламеризм есть - это когда путают Pchar, string и pointer, функцию ShowMessage и функцию Length и отладчик. А вообще не грех например пройтись отладчиком и посмтреть результат возврата итогового SendBuf и send.

    var
    s: string;
    begin
    s:= 'какая то '#00'строка...';

    ShowMessage(Copy(s, 1, 9)+Copy(s, 11, 9)); //данные есть, можно убедится
    ShowMessage(s);                            //а вот так?
    ShowMessage(IntToStr(Length(PChar(s))));   //а что думаеш покажет это?
    s:= 'какая то '#0#0'строка...';
    ShowMessage(IntToStr(Length(s)));   //а что думаеш покажет это?
    s:=#00;
    ShowMessage(IntToStr(Length(s)));   //а что думаеш покажет это?
     s:=#0#0;
    ShowMessage(IntToStr(Length(s)));   //а что думаеш покажет это?

  • Вариант (28.10.10 11:33) [34]

    > sniknik ©   (28.10.10 11:20) [32]

    Я просто хотел подчеркнуть, что SendText для отправки бинарного содержимого - это способ получить глюки, когда отправлются данные, сформированные по методу SendText(#01#0000 + там чего-то). Просто из-за того, что забыл где-то #
  • VFaust © (28.10.10 11:54) [35]
    Люди...!!! Вы в танке, что-ли...!!!

    Передаю ОДИН байт = 2 тетрады = 8 бит
    SendText(#00); это тоже самое, что и SendText(#0);


    > Вариант   (28.10.10 11:33) [34]

    спасибо за совет, но я использую другой метод
    Пример:#$03 + #$00 + #$00 + #$16 + #$11 + #$E0 + #$00 + #$00 + #$00 + #$02
  • Вариант (28.10.10 12:05) [36]

    > VFaust ©   (28.10.10 11:54) [35]

    Да не в танке. Проблема у тебя с приемом данных ты говоришь. Просто проблема с приемом потому, что или ты где-то не так что-то делаешь и скорее всего с контроллером, в работе с ним или в твоем коде например по получению данных чрезе ClientSocket например... (Конечно я могу и ошибаться, и код нормальный и протокол работы с утройством соблюден)
    Путь к тому как ты хотел читать как бы "сырые" данные тебе примерно указали ([17],[28],[29],[31]). Но это не решение проблемы, а "латание". А картинки которые ты привел - да это о чем-то говорит, что данные есть - но это одна и то неполная картинка плохого качества - по крайней мере я так увидел.  

    Ты [17] пробовал ? ПОлучил отрицательный или положительный результат для решения своей проблемы?
  • VFaust © (28.10.10 12:12) [37]
    БлагоДарю ВСЕМ...
    Я понял в каком направлении мне двигаться...

    > Сергей М. ©   (27.10.10 12:24) [17]
    >
    > ну если PSH не взведен во входящем пакете, то неудивительно
    > что 6 вошедших байт висят в буфере приема и не отдаются
    > приложению
    >
    > попробуй сразу после коннекта отключить буферизацию вх.потока
    > установкой в ноль опции SO_RCVBUF клиентского гнезда


    P.S. Я не говорю, что это ответ..., это направление...
  • Anatoly Podgoretsky © (28.10.10 12:14) [38]

    > спасибо за совет, но я использую другой метод

    Чем этот твой другой метод принципиально отличается от [34] использование знака плюс, так он не обязателен и принципа не меняет. Использованием хекс, тоже принципа не меняет.
  • VFaust © (28.10.10 12:47) [39]

    > Чем этот твой другой метод принципиально отличается от [34]
    > использование знака плюс, так он не обязателен и принципа
    > не меняет. Использованием хекс, тоже принципа не меняет.
    >

    Я не знал про это...

    Попробовал #$03#$00#$00#$16#$11#$E0#$00#$00#$00#$02 - работает, но это уже оффпот...
 
Конференция "Сети" » ClientSocket нет события onRead [D7, WinXP]
Есть новые Нет новых   [134436   +25][b:0][p:0.002]