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

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

Проблемы с получение hmtl страницы [D7, Win2k, WinXP]


IncubuS ©   (2004-04-29 11:08:00) 

Знакомый прислал исходник, написаный на C, для получения внешнего ip-адреса. Все у него работает, все замечательно. Я переделал его на Delphi и у меня возникли проблемы. Иногда при запросе страницы я получаю от сервера только шапку:

HTTP/1.0 200 OK
Server: Cherokee/0.4.6
Pragma: no-cache
Cache-Control: no-cache
Content-Type: text/html
Connection: close

И все, содержимого страницы нет. :( Иногда же все работает нормально. Причину выяснить я не могу, кроме того что ioctlsocket иногда возвращает размер шапки. Вот сам код:


uses Windows, WinSock;

{$APPTYPE CONSOLE}
{$DEFINE DEBUG}

function WaitForData(S: TSocket; nTimeout: Cardinal): Boolean;
var
 fdSet: TFDSet;
 T: Ttimeval;
 zSelect: Integer;
begin
 Result := False;
 FD_ZERO(fdSet);
 FD_SET(S, fdSet);
 T.tv_sec := nTimeout;
 T.tv_usec := 0;
 zSelect := select(0, @fdSet, nil, nil, @T);
 if (zSelect = SOCKET_ERROR) or not FD_ISSET(S, fdSet) then Exit;
 Result := True
end;

function GetOnlineIP(var szIPAddress: String): Boolean;
const
 AddrMask = 'Current IP Address:';
var
 Sock: TSocket;
 lpHostEntry: PHostEnt;
 saServer: TSockAddrIn;
 nRet, Size, lPos: Integer;
 DataIn, Request: String;
begin
 Result := False;
 szIPAddress := '';
 Sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if Sock = INVALID_SOCKET then Exit;
 try
   lpHostEntry := gethostbyname('checkip.dyndns.org');
   if lpHostEntry = nil then Exit;
   saServer.sin_family := AF_INET;
   saServer.sin_addr := PInAddr(lpHostEntry.h_addr_list^)^;
   saServer.sin_port := htons(8245);
   nRet := connect(Sock, saServer, SizeOf(saServer));
   if nRet = SOCKET_ERROR then Exit;
   Request := 'GET / HTTP/1.1'#13#10'Host: checkip.dyndns.org'#13#10#13#10;
   send(Sock, Request[1], Length(Request), 0);
   if not WaitForData(Sock, 5) then Exit;
   DataIn := '';
   repeat
     ioctlsocket(Sock, FIONREAD, Size);
     if Size > 0 then begin
       SetLength(DataIn, Size + Length(DataIn));
       if recv(Sock, DataIn[Length(DataIn) - Size + 1], Size, 0) = SOCKET_ERROR then Break;
     end;
{$IFDEF DEBUG}
     Writeln('Size: ', Size);
{$ENDIF}
   until Size = 0;
 finally
   CloseSocket(Sock);
 end;
{$IFDEF DEBUG}
 Writeln;
 Writeln(DataIn);
 Writeln;
{$ENDIF}
 lPos := Pos(AddrMask, DataIn);
 if lPos <> 0 then begin
   Delete(DataIn, 1, lPos + Length(AddrMask));
   szIPAddress := Copy(DataIn, 1, Length(DataIn) - Pos('<', DataIn));
   Result := True
 end
end;

var
 Version: Word;
 wsaData: TWSADATA;
 IPAddress: String;

begin
 Version := MAKEWORD(1, 1);
 WSAStartup(Version, wsaData);
 if GetOnlineIP(IPAddress) then
   Writeln('Your IP: ' + IPAddress);
 WSACleanup
end.


IncubuS   (2004-04-30 08:13:00) [1]

В моей конфигурации: адрес внешнего интерфейса машины, находящейся в локальной сети и на которой поднят NAT. При dialup: адрес ppp-интерфейса и т.п. и т.д.


Verg   (2004-04-30 08:06:00) [2]


> Локальные ip-адреса определить не проблема.


А какой же адрес ты получишь при помощи приведенного тобой кода?


IncubuS   (2004-04-30 08:00:00) [3]

Несколько и они находятся не на моей машине. ;) Локальные ip-адреса определить не проблема.


Verg   (2004-04-30 07:16:00) [4]


> IncubuS ©   (30.04.04 05:37) [4]
> Verg, этот способ определяет адрес интерфейса, через который
> я, находясь в локальной сети, хожу в инет. ;) А какие еще
> могут быть способы, буду рад узнать? ;-)


Т.е. надо понимать, что этих интерфейсов у тебя несколько?


IncubuS   (2004-04-30 05:37:00) [5]

Verg, этот способ определяет адрес интерфейса, через который я, находясь в локальной сети, хожу в инет. ;) А какие еще могут быть способы, буду рад узнать? ;-)


Verg   (2004-04-29 14:11:00) [6]


> IncubuS ©   (29.04.04 14:05) [2]


Объяснил бы - зачем тебе это?
Есть способы и проще узнать свой IP адрес :)))


IncubuS   (2004-04-29 14:05:00) [7]

Verg, большое тебе спасибо!


Verg   (2004-04-29 11:45:00) [8]

  DataIn := '';
  repeat
    if not WaitForData(Sock, 5) then break;
    if ioctlsocket(Sock, FIONREAD, Size) = SOCKET_ERROR then break;
    if Size > 0 then begin
    begin
      SetLength(DataIn, Size + Length(DataIn));
      Size := recv(Sock, DataIn[Length(DataIn) - Size + 1], Size, 0);
    end;
{$IFDEF DEBUG}
    Writeln('Size: ', Size);
{$ENDIF}
  until Size <= 0;


Наверх

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