[3H]:求教WININET中函数的正确调用(内附代码) (100分)

  • 主题发起人 主题发起人 3h
  • 开始时间 开始时间
3

3h

Unregistered / Unconfirmed
GUEST, unregistred user!
想连接到某一个地址中。
这个函数是分析URL的:
function TMainForm.ExtractServer(URL: String; var Port: Integer; var ServerName,
ObjectName, UserName, Password: String): DWord;
const
DefaultEmail = '';
var
I: Integer;
U, Svr: String;
begin
If Trim(URL) = '' then
begin
Result := 0;
Exit;
end;

I := Pos('://', URL);
Svr := LowerCase(Copy(URL, 0, I - 1));
If (Svr = 'http') or (Svr = 'https') then
Result := INTERNET_SERVICE_HTTP
else If Svr = 'ftp' then
Result := INTERNET_SERVICE_FTP
else If Svr = 'gopher' then
Result := INTERNET_SERVICE_GOPHER
else
begin
Result := 0;
Exit;
end;

Inc(I, 3);
URL := Copy(URL, I, MaxInt);

I := Pos('/', URL);
If I = 0 then
begin
ServerName := URL;
ObjectName := '/';
end
Else
begin
ServerName := Copy(URL, 0, I - 1);
ObjectName := Copy(URL, I, MaxInt);
end;

I := Pos('@', ServerName);
If I = 0 then
begin
UserName := '';
Password := DefaultEmail;
end
else
begin
UserName := Copy(ServerName, 0, I - 1);
ServerName := Copy(ServerName, I + 1, MaxInt);

I := Pos(':', UserName);
If I = 0 then
Password := DefaultEmail
else
begin
Password := Copy(UserName, I + 1, MaxInt);
UserName := Copy(UserName, 0, I - 1);
end
end;

I := Pos(':', ServerName);
If I = 0 then
Case Result Of
INTERNET_SERVICE_HTTP:
Port := INTERNET_DEFAULT_HTTP_PORT;
INTERNET_SERVICE_FTP:
Port := INTERNET_DEFAULT_FTP_PORT;
INTERNET_SERVICE_GOPHER:
Port := INTERNET_DEFAULT_GOPHER_PORT;
else
Port := INTERNET_DEFAULT_HTTPS_PORT;
end
else
begin
Port := StrToIntDef(Copy(ServerName, I + 1, MaxInt), -1);
If Port = -1 then
Case Result Of
INTERNET_SERVICE_HTTP:
Port := INTERNET_DEFAULT_HTTP_PORT;
INTERNET_SERVICE_FTP:
Port := INTERNET_DEFAULT_FTP_PORT;
INTERNET_SERVICE_GOPHER:
Port := INTERNET_DEFAULT_GOPHER_PORT;
else
Port := INTERNET_DEFAULT_HTTPS_PORT;
end;
ServerName := Copy(ServerName, 0, I - 1);
end;
ServerName := ServerName + #0;
end;

经测试,分析的结果是正确的。
然后放一个按钮:

procedure TMainForm.BtnClick(Sender: TObject);
const
MaxLen = 1024;
var
URL: String;
AcceptTypes: LPSTR;
Hi, Hc, Hh: HINTERNET;
I, ServerType, Index, Len: DWORD;
Buf: String;

Port, Context: Integer;
ServerName, ObjectName, UserName, Password: String;
begin
URL := 'http://glowing.sw163.net/index.asp';
ServerType := ExtractServer(URL, Port, ServerName,
ObjectName, UserName, Password);
If ServerType <> 0 then
begin
SetLength(Buf, MaxLen);
Len := MaxLen;
AcceptTypes := 'text/*';

Hi := InternetOpen('Glowing He', INTERNET_OPEN_TYPE_DIRECT,
Nil, Nil, 0);
Hc := InternetConnect(Hi, PChar(ServerName),
Port,
PChar(UserName), PChar(Password),
ServerType, 0, 0);
I := GetLastError;
If I <> 0 then
begin
ShowMessage(IntToStr(I));
InternetGetLastResponseInfo(I, PChar(Buf), Len);
If Len > 0 then
ShowMessage(Copy(Buf, 0, Len));
Exit;
end;

Hh := HttpOpenRequest(
Hc,
Nil,
PChar(ObjectName),
Nil,
PChar(URL),
@AcceptTypes,
INTERNET_FLAG_DONT_CACHE or INTERNET_FLAG_NO_AUTO_REDIRECT,
0);
I := GetLastError;
If I <> 0 then
begin
ShowMessage(IntToStr(I));
InternetGetLastResponseInfo(I, PChar(Buf), Len);
If Len > 0 then
ShowMessage(Copy(Buf, 0, Len));
Exit;
end;

If Hh <> Nil then
begin
SetLength(Buf, MaxLen);
Len := MaxLen;
HttpQueryInfo(Hh, HTTP_QUERY_STATUS_TEXT, PChar(Buf), Len, Index);
Showmessage(inttostr(Len) + ', ' + inttostr(index));
showmessage(Copy(buf, 0, Len));
InternetCloseHandle(Hh);
end;
InternetCloseHandle(Hc);
InternetCloseHandle(Hi);
end;
end;

按理说,在执行InternetConnect的时候应该是很慢的,因为它要连接到一个网站上,
事实上执行起来特快——不可能吧,我用的是56K的MODEM:)
而且结论也是不正确的,总是显示“0,0”的窗口。

故求哪位高手哥们指点一下迷津,谢谢!
 
> 按理说,在执行InternetConnect的时候应该是很慢的,因为它要连接到一个网站上
不对,文档说,只有ftp才是实际连接到服务器,而其他的服务,连接是要在后继的
实际请求的时候才做的。原文如下:
For FTP sites, InternetConnect actually establishes a connection with the server;
for others, such as Gopher, the actual connection is not established
until the application requests a specific transaction.

 
HttpOpenRequest的参数: @AcceptTypes 不对
1、你的是text/*,其实这个参数可以简单以 nil 代替
2、如果你不用nil,那么文档上说,这个参数是:
Address of a null-terminated array of string pointers indicating media types accepted by the client.
就是说,要以nil结束的数组,那么你要这样来:
var arr:array[0..1] of PChar;
arr[0]:=AcceptTypes;
arr[1]:=nil; //nil表示数组结束了
然后把arr作为参数
 
先谢谢PIPI大哥。

关于连接的问题,我觉得即使InternetConnect可以快,
那么按MS的说法HttpOpenRequest应该慢呀,可以事实的确很快:)

参数的问题,我先置为NIL,不行:(
试试这样
var
Accept: Array[0..1] of PChar;
...
Accept[0] := 'text/*';
Accept[1] := Nil;
Hh := HttpOpenRequest(Hc,
Nil,
PChar(ObjectName),
Nil,
Nil,
Accept,
INTERNET_FLAG_DONT_CACHE or INTERNET_FLAG_NO_AUTO_REDIRECT,
0);
编译器报错,说是:
[Error] MAIN.pas(1163): Incompatible types: 'Array' and 'PLPSTR'
改成@Accept后仍旧是“0,0”的结果,即使URL是一个不可能到达的地址。
 
一个问题是: http://glowing.sw163.net/index.asp
我用ie都打不开呀:)
 
还有啊,我一直做到 HttpOpenRequest 都是正常的
HttpOpenRequest 之后为什么就 HttpQueryInfo 呢
HttpOpenRequest 之后你还没有 HttpSendRequest 呢
 
呵呵,我就是要用一个打不开的地址来测试效果:)

问题已经找到了,就是这个,从MS的SDK来的:

The HttpOpenRequest function opens an http request and returns an HINTERNET
handle that can be used by the other http functions. Unlike the other open
functions (such as FtpOpenFile and InternetOpenUrl), HttpOpenRequest does not
send the request to the Internet when called. The HttpSendRequest function
sends the request and establishes a connection over the network.

原来 HttpOpenRequest 也是没有真正发请求的,要用到 HttpSendRequest。
已经成功了,正确的代码过些时间我再贴出来。

万分的感谢 PIPI 兄弟,真是好哥们!:)
 
其实WinInet中已经有了一个函数可以分析URL
function InternetCrackUrl(lpszUrl: PChar; dwUrlLength, dwFlags: DWORD;
var lpUrlComponents: TURLComponents): BOOL; stdcall;
 
...
Case ServerType Of
INTERNET_SERVICE_HTTP,
INTERNET_SERVICE_HTTPS:
begin
INTERNET_FLAG := INTERNET_FLAG_DONT_CACHE
or INTERNET_FLAG_NO_AUTO_REDIRECT
or INTERNET_FLAG_PRAGMA_NOCACHE
or INTERNET_FLAG_RELOAD
or INTERNET_FLAG_RESYNCHRONIZE
or INTERNET_FLAG_KEEP_CONNECTION;
If ServerType = INTERNET_SERVICE_HTTPS then
INTERNET_FLAG := INTERNET_FLAG or INTERNET_FLAG_SECURE;

H_HTTP_OPEN := HttpOpenRequest(H_INET_CONN, Nil, PChar(ObjectName),
Nil, Nil, Nil, INTERNET_FLAG, 0);
If H_HTTP_OPEN <> Nil then
begin
HttpSendRequest(H_HTTP_OPEN, Nil, 0, Nil, 0);

I := GetLastError;
If I <> 0 then
State := GetClassify(I)
else
begin
SetLength(Buf, MaxLen);
Len := MaxLen;
Index := 0;
HttpQueryInfo(H_HTTP_OPEN, HTTP_QUERY_STATUS_CODE, PChar(Buf),
Len, Index);
ShowMessage(Copy(buf, 0, Len));
// 状态字
end;
// Close the HTTP connection.
InternetCloseHandle(H_HTTP_OPEN);
end;
end; // end HTTP
...
 
3h,500分求你的代码,我实在是头的都大了
 

Similar threads

I
回复
0
查看
710
import
I
I
回复
0
查看
666
import
I
I
回复
0
查看
684
import
I
I
回复
0
查看
515
import
I
I
回复
0
查看
826
import
I
后退
顶部