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

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

сокеты и web service [D6, Win2k]


Страницы:   1 2 3

Lesorub ©   (2006-11-16 18:34:00) 

Вот у меня в сетке есть web-сервер (апач на winnt).  Хотелось бы чтобы web service на нем, при обращении клиента, брал  с другого сервера в сетке (где БД) данные. Для этого я попробовал использовать ClientSocket поместив его в Web-module web service 'а, как это делается в обычных приложениях. Компиляция прошла без проблем, но при запросе программки-клиента, когда происходило событие ClientSocket.Open, выскочила ошибка Access Violation at address такого-то in module таком-то. Read of address такой-то. И информации толком нигде нет по этой теме, в общем, плз, very need help )


Lesorub   (2006-11-25 11:21:00) [1]

Читал много. Размышлял.
В общем, действительно это глупость использовать задержку. Совершенно согласен теперь с тем, что, в случае асинхронных сокетов, надо писать класс с эвентами, чтобы обрабатывать те самые оконные сообщения, либо использовать синхронные. Сначала пробую использовать синхронные. Причем решил не использовать vcl, а использовать api-функции winsock, поскольку в этом случае приложение как-то более контролируемо.
  Делаю подготовку так:
  if wsastartup($101,vwsadata)<>0 then halt(1);
  vsocket := socket(af_inet,sock_stream,ipproto_ip); //создается сокет
  if vsocket = invalid_socket then halt(1);
  fillchar(vsockaddr,sizeof(tsockaddr),0);
  vsockaddr.sin_family := af_inet;
  vsockaddr.sin_port := htons(cport);
  vsockaddr.sin_addr.s_addr := inet_addr(ip);
  if connect(vsocket,vsockaddr,sizeof(tsockaddr)) = socket_error then halt(1);
  //затем отсылаем данные
  send(vsocket,buf[1],length(buf),0);
  //затем надо принять ответ

  recv(vsocket,chresp,1,0);
То есть хочу считывать по одному байту, и с этой целью надо поместить recv в цикл. И вот тут как определить сколько данных пришло в сокет?
А так вроде работает. Как думаете, правильно так делать?


MikePetrichenko   (2006-11-20 10:03:00) [2]


> НО! Теперь пишет, после того как поставил паузу, ошибку
> показывает такую:  InternalServerError (500)

Правильно пишет.
Вообще это идиотизм, использовать асинхронные сокеты с процедурой задержки, уж простите.
Пользуй либо синхронные, либо события OnConnect OnDisconnet.
P.S. В дельфе асинхронная работа сокетов сделана на основе оконных сообщений (что ни есть гуд для CGI). Следствие. Пиши ручками с использование Event, либо пользуй синхронные, либо события.


Сергей М.   (2006-11-20 08:10:00) [3]


> Lesorub ©   (19.11.06 20:52) [41]


Не надо сокету давать никакую "паузу".
Либо установи ctBlocking, либо органигуй цикл ожидания/выборки/диспетчеризации оконных сообщений.


Lesorub   (2006-11-19 20:52:00) [4]

хм, но что же тогда, почему же ошибка возникает когда сокету дается время (пауза 10 сек) на открытие


Anatoly Podgoretsky   (2006-11-19 20:32:00) [5]

> Lesorub  (19.11.2006 20:22:39)  [39]

Думаем, что нет, поскольку cgi это обычное консольное приложение


Lesorub   (2006-11-19 20:22:00) [6]

а может запрещено winsock.dll исользовать в cgi, как думаете?


Lesorub   (2006-11-19 13:52:00) [7]

Код процедуры "пауза"  без ошибок


Lesorub   (2006-11-19 13:29:00) [8]

ага, но откуда!


Anatoly Podgoretsky   (2006-11-19 13:05:00) [9]

> Lesorub  (19.11.2006 11:46:35)  [35]

Так у тебя ошибка в сервисе.


Lesorub   (2006-11-19 11:46:00) [10]

НО! Теперь пишет, после того как поставил паузу, ошибку показывает такую:  InternalServerError (500)


Lesorub   (2006-11-19 11:39:00) [11]

Кстати, теперь после S.Open делаю паузу 10 секунд с помощью Application.ProcessMessages и цикла. Неужели 10 секунд не хватает чтобы перейти S.Active в true !


Lesorub   (2006-11-19 11:30:00) [12]

Ок, надо почитать :-)


MikePetrichenko   (2006-11-19 11:28:00) [13]

Тогда он практически НИКОГДА не будет сразу Active = True. Читай про Overlapped IO и Thread blocking sockets.
Думай. И будет тебе просветление.


Lesorub   (2006-11-19 11:23:00) [14]

non blocked, в асинхронном режиме
пишу так:
S.ClientType:=ctNonBlocking;


MikePetrichenko   (2006-11-19 11:20:00) [15]


> хм, может ему какое-то время надо на открытие

Сокет Blocked или Non Blocked?


Lesorub   (2006-11-19 10:15:00) [16]

хм, может ему какое-то время надо на открытие


Lesorub   (2006-11-19 10:08:00) [17]

теперь то что ему не хватает


Lesorub   (2006-11-19 10:08:00) [18]

ага, но без этих строчек
S.Close;
S.Free;
все равно то же самое...

после S.Open пишу
if S.Active=true then  Conn:='active'
         else Conn:='not active';

а потом наблюдаю за переменной Conn - 'not active', вот ведь как.


MikePetrichenko   (2006-11-19 09:59:00) [19]


> S.Open;
> S.Close;
> S.Free;

Так ты же его сразу закрываешь.


Lesorub   (2006-11-19 09:55:00) [20]

Вот, теперь делаю так:
var
S: TClientSocket;
...
//создаем
S:=TClientSocket.Create(self);
S.Address:='127.0.0.1';
S.Port:=80;
S.Open;
S.Close;
S.Free;

Достижение, обращение клиента проходит нормально. Но зато другая появилась проблема - при открытии сокета свойство Active не переходит в true, даже если явно указать после S.Open строку S.Active:=true.


Страницы:   1 2 3

Наверх

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