Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];

Вниз

ClientSocket -- получение ответа на запрос   Найти похожие ветки 

 
Ypbi4 ©   (2007-04-23 13:53) [0]

Добрый весна всем :)
Есть проблемка интересная:
Через Clientsocket  в режиме ctNonBlocking отправляется запрос на сервер  и с него получаю ответ, этот ответ нужно обработать. Вроде ничего сложного, но есть запарка: нужно отправить несколько параметров и от каждого получить ответ, верный он или нет(верный то содержит в ReciveText 250 ok нет 500 Error). и такх запросов за один сеанс порядка 12000. Я реализовал ето так:
Создал поток thread  и заключил в него процедуры
           MainForm.SNPP.Socket.SendText("PAGER"+" "+tel+#10);
           sleep(time2); // задержка что бы  дождаться данных
           recive:=MainForm.SNPP.Socket.ReceiveText;
           if POS("250",recive) = 0 then // если не принято, то пишется ошибка
             Begin
               zapis:="Неверный формат номера"+#10#13+recive;
               MainForm.SNPP.Socket.SendText("RESET"+#10);
               synchronize(UpdateMemo);
             end;
Дело в том что это занимает очень много времени, может как то можно ускорить процесс обмена :( И данные могут склеиваться т.е. может прийти ответ на пару запросов.
На сайте в FAQ нашел пример похожий но это не то :(

 s:= Socket.ReceiveText;
 // Если мы не в режиме приёма:
 if not Reciving then
 begin
   // Теперь нам необходимо получить длину потока данных.
   SetLength(sl, StrLen(PChar(s))+1); // +1 for the null terminator
   StrLCopy(@sl[1], PChar(s), Length(sl)-1);
   DataSize:= StrToInt(sl);
   Data:= TMemoryStream.Create;
   // Удаляем информацию о размере из данных.
   Delete(s, 1, Length(sl));
   Reciving:= true;
 end;
 // Сохраняем данные в файл, до тех пор, пока не получим все данные.
 try
   Data.Write(s[1], length(s));
   if Data.Size = DataSize then
   begin
     Data.Position:= 0;
     Image2.Picture.Bitmap.LoadFromStream(Data);
     Data.Free;
     Reciving:= false;
     Socket.Close;
   end;
 except
   Data.Free;
 end;
end;
Помогите советом плз ;)


 
Сергей М. ©   (2007-04-23 14:12) [1]


> sleep(time2); // задержка что бы  дождаться данных


Зачем их "дожидаться" ?

На то есть событие OnRead.


 
Ypbi4 ©   (2007-04-23 14:31) [2]

Хорошо. Допустим я обрабатываю событие OnRead:
Отослал запрос мне в ответ пришла строка содержащая "250  bla bla bla"
и Дальше что? посылать следующий запрос? Подскажи как реализовать то?
Еще есть запросы допустим query <message_id>  и в ответ приходит "ready" или тип того, Мне нужно эти данные обработать (внести в базы и т.д.) . А ждет отправки много всего. есть ли алгоритм вроде
SendCmd(), я пробовал но меня он ошибку выдает :(  ?


 
Ypbi4 ©   (2007-04-23 14:33) [3]

это протокол SNPP, только расширеный разроботчиком. есть Indy компанент, но с ним работать нельзя :(.


 
Сергей М. ©   (2007-04-23 14:43) [4]


> есть Indy компанент, но с ним работать нельзя


Почему ?
И если нельзя, то почему не проанализировать как это сделано в Инди, благо исходники открыты ?


 
Ypbi4 ©   (2007-04-23 15:01) [5]

Indy использует неблокирущие сокеты :(


 
Ypbi4 ©   (2007-04-23 15:02) [6]

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


 
Сергей М. ©   (2007-04-23 15:03) [7]


> Indy использует неблокирущие сокеты


И что ?
Это как-то межает реализации задачи ?


 
Ypbi4 ©   (2007-04-23 15:12) [8]

Есть немного :)
указываю хост, порт при попытке коннекта выдается ошибка
"
exception class EDIdSNPPConnectionRefused with message + первая строка приветствия сервера
"
Потом приложение вылетает :(.


 
Сергей М. ©   (2007-04-23 15:16) [9]


> Ypbi4 ©   (23.04.07 15:12) [8]


А причем здесь блокирующий режим ?


 
Ypbi4 ©   (2007-04-23 15:24) [10]

хм, а примерно что это может значить тогда :)? Почему отрубается соединение?


 
Сергей М. ©   (2007-04-23 15:32) [11]


> что это может значить тогда


То что в приветствии отсутствует код 220


 
Ypbi4 ©   (2007-04-23 15:45) [12]

Нравится это общение...
ок, ясно, допустим есть такое в у компанента. Теперь это можно обойти ? обрабатывать событие onError, так я понимаю? И его сделать как исключение?


 
Ypbi4 ©   (2007-04-23 15:57) [13]

кстати о птичках.. в приветствии есть код 220


 
Сергей М. ©   (2007-04-23 16:00) [14]


> допустим есть такое в у компанента


Компонент "заточен" под стандартный SNPP, а не под вольную его трактовку шлюз-сервером ретивого SMS-провайдера.

А стандартный SNPP предполагает приветствие, начинающееся с "220", а не с чего-то другого.

Исходя из этого "обходить" ситуацию в TIdSNPP с нестандартным приветствием SNPP-сервера имеет смысл лишь при  условии, что это единственный "нестандарт" в "расширенном протоколе". В противном случае (нестандарты везде и всюду) придется реализовать собственный SNPP-клиент, на базе хотя бы того же TIdTCPClient


 
Сергей М. ©   (2007-04-23 16:06) [15]


> в приветствии есть код 220


Я извиняюсь, ситуация строго обратная - IdSMPP при коннекте реагирует упомянутым тобой образом лишь в случае, когда в строке приветствия код 220 присутствует.

Вот цитата из исходников TIdSNPP:

procedure TIdSNPP.Connect(const ATimeout: Integer = IdTimeoutDefault);
begin
 inherited Connect(ATimeout);
 try
   if GetResponse([]) = 220 then begin
     raise EIdSNPPConnectionRefused.CreateError(502, LastCmdResult.Text.Text);
   end;
 except
   Disconnect;
   Raise;
 end;
end;

Как видишь, ситуация с исключением и дисконнектом как раз и возникает по этой причине.

Если это баг в компоненте - а это оч похоже на баг - попробуй обновить версию Инди до 10-ки, возможно там этот баг исправлен.


 
Сергей М. ©   (2007-04-23 16:11) [16]

В противном случае (нежелательность обновления Инди) можно подправить баг собственноручно - ничто этому не препятствует.


 
Ypbi4 ©   (2007-04-24 14:48) [17]

В моей версии Indy был баг :) GetResponse([]) = 220 then надо заменить на
GetResponse([]) <> 220 then begin. Скачал Indy 10, что бы обновить, но при установке наверное что то случилось и Delphi запускается с ошибками и в итоге никакого обновление не произошло. Пытался сам исправить в делфи ту строку (мне еще туда надо новые функции фтюхать) но что то запарился, не смог откомпилить... все еду домой пить пиво


 
Сергей М. ©   (2007-04-24 14:55) [18]


> все еду домой пить пиво


Перед этим не забудь запустить "format C:"


 
Ypbi4 ©   (2007-04-25 11:49) [19]

Установил Indy 10...
SNPP - сервер явно не стандартен.... Теперь придется писать свой компанент. Работает стабильно одна процедура -- connect :))


 
Сергей М. ©   (2007-04-25 15:31) [20]


> SNPP - сервер явно не стандартен


Значит этот сервер есть черт-те что, но только не SNPP-сервер.


 
Ypbi4 ©   (2007-04-26 15:35) [21]

Сервер написан по протоколу SNPP до 3 levela. Т.е все команды реализованы, видимо кому то руки надо поправить...(кто пишет клиентскую часть), т.к. уже есть хорошая реализация клиента, но делится исходниками не хотят. Искал по инету компаненты, где реализовано, для делфи нет :(.
Пытаюсь сам написать на основе Indy, но т.к. первый раз пишу компанент, то херова получается, точнее никак :))

Думаю тема должна быть закрыта и открыта новая :)


 
Сергей М. ©   (2007-04-26 15:39) [22]


> первый раз пишу компанент


А за каким лядом ты пишешь именно компонент ?
Чем это оправдано ?


 
Ypbi4 ©   (2007-04-26 15:51) [23]

Это оправдано тем, что я буду его не раз использовать, есть уже написаный (Indy), т.е. есть аналог. Или есть альтернатива? Можно конечно dll-ку или просто шаблончик сделать. Большого опыта у меня нет, поэтому на мой взгляд лучше написать компонент. Если есть лучшая альтернатива, то я готов выслушать :) и принять к сведению.


 
Сергей М. ©   (2007-04-26 16:03) [24]


> Ypbi4 ©   (26.04.07 15:51) [23]



> не раз использовать


Оправдания приняты)


 
Ypbi4 ©   (2007-04-28 10:04) [25]

Кхы, написал :) SNPP level 3


 
Ypbi4 ©   (2007-04-28 10:13) [26]

Теперь проблема появилась.

function TIdSNPP.xPager(xPg: string): String;
begin
 Result := "";
 Writeln("PAGER " + xPg);    {Do not Localize}
 if GetResponse([]) = 250 then begin
   Result :=LastCmdResult.Text.Text;
 end else begin
   Result :="ERROR "+LastCmdResult.Text.Text;
 end;
end;

В результате функции получаю ответ LastCmdResult.Text.Text  для дальнейшей обработки,НО у меня таких функций несколько, в результате у меня не присылается частенько последние данные (хотя смс отправляется резво). Пробовал ставить sleep, antifreez ставил, но ничего хорошего не выходит :(. Вопрос в чем, как уменьшить скорость отпраки :), что бы перехватить данные и корректно их обработать?



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.007 c
2-1197846653
Koss
2007-12-17 02:10
2008.01.13
как создать TImage в режиме run-time


15-1196967066
Light
2007-12-06 21:51
2008.01.13
Вопрос о роуминге


15-1196978196
Lip
2007-12-07 00:56
2008.01.13
Delphi -> Console Application


15-1197187860
yeees
2007-12-09 11:11
2008.01.13
Большой вопрос


2-1197810242
Riply
2007-12-16 16:04
2008.01.13
Свободные Windows Error - ы :)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский