![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
после 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() последний параметр. Или неблокирующие сокеты и собственный отсчет времени.