Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

ClientSocket -- получение ответа на запрос [D7, WinXP]


Страницы:   1 2

Ypbi4 ©   (2007-04-23 13:53:00) 

Добрый весна всем :)
Есть проблемка интересная:
Через 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;
Помогите советом плз ;)


Ypbi4   (2007-04-28 10:13:00) [1]

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

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 ставил, но ничего хорошего не выходит :(. Вопрос в чем, как уменьшить скорость отпраки :), что бы перехватить данные и корректно их обработать?


Ypbi4   (2007-04-28 10:04:00) [2]

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


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


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



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


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


Ypbi4   (2007-04-26 15:51:00) [4]

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


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


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


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


Ypbi4   (2007-04-26 15:35:00) [6]

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

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


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


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


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


Ypbi4   (2007-04-25 11:49:00) [8]

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


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


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


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


Ypbi4   (2007-04-24 14:48:00) [10]

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


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

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


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


> в приветствии есть код 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:00:00) [13]


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


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

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

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


Ypbi4   (2007-04-23 15:57:00) [14]

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


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

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


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


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


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


Ypbi4   (2007-04-23 15:24:00) [17]

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


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


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


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


Ypbi4   (2007-04-23 15:12:00) [19]

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


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


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


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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо