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

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

после recv виснет


Res ©   (2008-05-05 14:33:00) 

Здравствуйте. У меня проблема в том, что после recv, функция зависает и перестает работать, но данная проблема только с yandex.ru(ya.ru), подскажите пожалуйста, как ограничить время выполнения recv или этого участка кода.


function getpage(url:string):string;
var
 D:WSAData;
 S:TSocket;
 A:TSockAddr;
 name,path:string;
 buff:array[0..1023] of char;
 httpsend,httpresponse:string;
 recived,n:integer;
begin
httpresponse:='';
{Ñíà÷àëà ïðîâåðÿåì ïðàâèëüíîñòü...}
if(copy(url,1,7)'http://') then
begin
exit;
end;
url:=copy(url,8,length(url));
n:=Pos('/',url);
if(n=0) then
begin
 name:=copy(url,1,length(url));
 path:='/';
end
else
begin
 name:=copy(url,1,n-1);
 path:=copy(url,n,length(url));
end;
{Ñòàðòóåì}
 if WSAStartup($101,D)0 then
 begin
   result:='';
   WSACleanup;
   exit;
 end;
{ Îïðåäåëÿåì òèï ñåìåéñòâà ñîêåòîâ, è IP àäðåñ äëÿ ñêàíèðîâàíèÿ }
A.sin_family:=AF_INET;
A.sin_addr.S_addr:=inet_addr(pChar(NameToIP(name)));
A.sin_port:=htons(80);
S:=socket(AF_INET,SOCK_STREAM,0);
if S=INVALID_SOCKET then
begin
   result:='';
   WSACleanup;
   exit;
end;
if connect(S,A,sizeof(A))0 then
begin
   result:='';
   WSACleanup;
   exit;
end;
{Ïîñòðîåíèå çàïðîñà}
httpsend:='GET '+path+' HTTP/1.1'+#13#10+
          'Host: '+name+#13#10+
         'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9'+#13#10+
          'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'+#13#10+
          'Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3'+#13#10+
          'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7'+#13#10+
          'Keep-Alive: 300'+#13#10+
          'Connection: keep-alive'+#13#10#13#10;
try
  send(s, HTTPSend[1], 1024,0);
except
   result:='';
   WSACleanup;
   exit;
end;
recived:=1;
while(recived>0) do
begin
   try
     Recived:=Recv(s,buff,1024,0);
   except
     result:=httpresponse;
     WSACleanup();
     exit;
   end;
   messagebox(0,PAnsiChar('asdasd'),'11',0);
   HttpResponse:=httpresponse+Copy (Buff,1,Recived);
 end;
result:=httpresponse;
WSACleanUp;
end;


Сергей М.   (2008-05-06 09:17:00) [1]


> Res


Тебе же уже сказали, что WinsockAPI-функции невозбуждают исключений, а ты по-прежнему продолжаешь их ловить с упорством, достойным лучшего применения)


DVM   (2008-05-05 22:56:00) [2]


> Или я неправильно сделал или это непашет :(

Ты неправильно сделал, разумеется.

 FD_ZERO(Rfds);
 FD_SET(Sock, Rfds);
 Found := select(Sock, @Rfds, nil, nil, @FTimeout);
 if Found = 0 then
   begin
     // Select timed out
     Result := -1;
     exit;
   end
 else
   if Found = SOCKET_ERROR then
     begin
       // Select error
       Result := -1;
       exit;
     end;
 // Если добрались сюда, то можно начинать читать

Правда, перед чтением хорошо бы еще проверить, что есть вообще что читать:

ioctlsocket(Sock, FIONREAD, TotalBytesToRead)


Res   (2008-05-05 16:03:00) [3]

Сделал с помошью select. Или я неправильно сделал или это непашет :(
Подскажите пожалуйста, где я ошибся
function getpage(url:string):string;
var
 D:WSAData;
 S:TSocket;
 A:TSockAddr;
 name,path:string;
 buff:array[0..1023] of char;
 httpsend,httpresponse:string;
 recived,n:integer;
 FDSet:TFDSet;
 tv: timeval;
begin
tv.tv_sec:= 20; //timeout 20 seconds
tv.tv_usec:= 0;
httpresponse:='';
{Сначала проверяем правильность...}
if(copy(url,1,7)<>'http://') then
begin
exit;
end;
url:=copy(url,8,length(url));
n:=Pos('/',url);
if(n=0) then
begin
 name:=copy(url,1,length(url));
 path:='/';
end
else
begin
 name:=copy(url,1,n-1);
 path:=copy(url,n,length(url));
end;
{Стартуем}
 if WSAStartup($101,D)<>0 then
 begin
   result:='';
   WSACleanup;
   exit;
 end;
{ Определяем тип семейства сокетов, и IP адрес для сканирования }
A.sin_family:=AF_INET;
A.sin_addr.S_addr:=inet_addr(pChar(NameToIP(name)));
A.sin_port:=htons(80);
S:=socket(AF_INET,SOCK_STREAM,0);
if S=INVALID_SOCKET then
begin
   result:='';
   WSACleanup;
   exit;
end;
if connect(S,A,sizeof(A))<>0 then
begin
   result:='';
   closesocket(s);
   WSACleanup;
   exit;
end;
{Подготавливаем сокет}
FD_Zero(FDSet);
Select(0,@FDSet,nil,nil,@tv);
if FD_IsSet(S,FDSet) then
begin
   messagebox(0,PAnsiChar('Урааа'),'11',0);
end;
{Построение запроса}
httpsend:='GET '+path+' HTTP/1.1'+#13#10+
          'Host: '+name+#13#10+
         'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9'+#13#10+
          'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'+#13#10+
          'Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3'+#13#10+
          'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7'+#13#10+
          'Keep-Alive: 300'+#13#10+
          'Connection: keep-alive'+#13#10#13#10;
try
  send(s, HTTPSend[1], 1024,0);
except
   result:='';
   closesocket(s);
   WSACleanup;
   exit;
end;
recived:=1;
while(recived>0) do
begin
   messagebox(0,PAnsiChar('asdasd'),'11',0);
   try
   Recived:=Recv(s,buff,1024,0);
   messagebox(0,PAnsiChar('asdasd'),'11',0);
   except
     result:=httpresponse;
     closesocket(s);
     WSACleanup();
     exit;
   end;
   messagebox(0,PAnsiChar('asdasd'),'11',0);
   HttpResponse:=httpresponse+Copy (Buff,1,Recived);
 end;
result:=httpresponse;
closesocket(s);
WSACleanUp;
end;

end.


Res   (2008-05-05 14:49:00) [4]


> Select() последний параметр

А есть какой - нибудь примерчик?
не дружу я с с++ :( Первые 4 параметра, мне не понятны
int select (

   int nfds,
   fd_set FAR * readfds,
   fd_set FAR * writefds,
   fd_set FAR * exceptfds,
   const struct timeval FAR * timeout
  );


DVM   (2008-05-05 14:39:00) [5]


> как ограничить время выполнения recv или этого участка кода.

Select() последний параметр.  Или неблокирующие сокеты и собственный отсчет времени.


Наверх

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