问题标签 [wininet]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1695 浏览

.net - 有关 InternetOpenUrl 和 InternetReadFile 的帮助API

我正在尝试使用 WinInet API 简单地访问页面。一旦我访问它,我希望能够将内容读入字符串。我已经初始化了根节点。这是我到目前为止得到的:

在此之后,我知道您必须使用 InternetReadFile 来实际提取数据。有人可以提供一个详细的例子来说明如何做到这一点。我对 C 风格的文件函数和使用缓冲区不是特别熟悉,所以请放轻松。

另一方面,我应该使用不同或更现代的 Windows API 来代替吗?从长远来看,我被分配开发一个应用程序,该应用程序将充当客户端并使用 HTTP 和 HTTPS 与远程服务器一起发送/接收数据。我在这里走对路了吗?

编辑:更具体的要求:它必须用 C++ 编写,必须与 Win XP 及更高版本兼容,并且必须仅使用标准 Windows 库。除此之外,我可以随心所欲。

0 投票
2 回答
5070 浏览

c++ - WinINet 异步模式灾难

抱歉问了这么长的问题。只是我花了几天时间试图解决我的问题,我已经筋疲力尽了。

我正在尝试在异步模式下使用 WinINet。我必须说……这简直是了。我真的无法理解这一点。它做了很多事情,但不幸的是,它的异步 API 设计得非常糟糕,以至于它不能用于具有高稳定性要求的严肃应用程序中。

我的问题如下:我需要连续执行大量 HTTP/HTTPS 事务,而我还需要能够在请求时立即中止它们。

我打算按以下方式使用 WinINet:

  1. InternetOpen通过带有INTERNET_FLAG_ASYNC标志的函数初始化 WInINet 的使用。
  2. 安装一个全局回调函数(通过InternetSetStatusCallback)。

现在,为了执行我想做的交易:

  1. 分配每个事务结构,其中包含描述事务状态的各种成员。
  2. 调用InternetOpenUrl以启动交易。在异步模式下,它通常会立即返回一个错误,即ERROR_IO_PENDING. 它的参数之一是“上下文”,将传递给回调函数的值。我们将其设置为指向每个事务状态结构的指针。
  3. 在此之后不久,全局回调函数被调用(从另一个线程) status INTERNET_STATUS_HANDLE_CREATED。此时我们保存 WinINet 会话句柄。
  4. INTERNET_STATUS_REQUEST_COMPLETE当事务完成时,最终调用回调函数。这允许我们使用一些通知机制(例如设置事件)来通知发起线程事务已完成。
  5. 发出事务的线程意识到它已经完成。然后它进行清理:关闭 WinINet 会话句柄 (by InternetCloseHandle),并删除状态结构。

到目前为止,似乎没有问题。

如何中止正在执行的事务?一种方法是关闭相应的 WinINet 句柄。而且由于 WinINet 没有诸如InternetAbortXXXX关闭句柄之类的功能,因此似乎是中止的唯一方法。

这确实奏效了。这样的事务立即完成并带有ERROR_INTERNET_OPERATION_CANCELLED错误代码。但是这里所有的问题都开始了......

我遇到的第一个令人不快的意外是 WinINet 有时会调用事务的回调函数,即使已经被中止。根据 MSDN,这INTERNET_STATUS_HANDLE_CLOSING是回调函数的最后一次调用。但这是一个谎言。我看到的是,有时会INTERNET_STATUS_REQUEST_COMPLETE针对同一个句柄发出相应的通知。

我还尝试在关闭它之前禁用事务句柄的回调函数,但这没有帮助。看来WinINet的回调调用机制是异步的。因此 - 即使事务句柄已关闭,它也可能调用回调函数。

这带来了一个问题:只要 WinINet可以调用回调函数——显然我无法释放事务状态结构。但是我怎么知道 WinINet 是否会这么好意地称呼它呢?从我所看到的 - 没有一致性。

尽管如此,我已经解决了这个问题。相反,我现在保留已分配事务结构的全局映射(当然受关键部分保护)。然后,在回调函数内部,我确保事务确实存在并在回调调用期间锁定它。

但是后来我发现了另一个问题,到目前为止我无法解决。当我在交易开始后不久就中止交易时,就会出现这种情况。

发生的事情是我调用InternetOpenUrl,它返回ERROR_IO_PENDING错误代码。然后我只是等待(通常很短),直到回调函数将被INTERNET_STATUS_HANDLE_CREATED通知调用。然后 - 事务句柄被保存,所以现在我们有机会在没有句柄/资源泄漏的情况下中止,我们可以继续。

我试图在这一刻之后进行中止。即在我收到后立即关闭此句柄。猜猜会发生什么?WinINet 崩溃,内存访问无效!这与我在回调函数中所做的任何事情都无关。甚至没有调用回调函数,崩溃发生在 WinINet 的深处。

另一方面,如果我等待下一个通知(例如“解析名称”)-通常它会起作用。但有时也会崩溃!Sleep如果我在获取句柄和关闭它之间做一些最小化,问题似乎就消失了。但显然这不能被接受为一个严肃的解决方案。

所有这一切让我得出结论:WinINet 设计不佳。

  • 对于特定会话(事务)的回调函数调用范围没有严格的定义。
  • 关于允许我关闭 WinINet 句柄的那一刻,没有严格的定义。
  • 谁知道还有什么?

我错了吗?这是我不明白的事情吗?还是 WinINet 无法安全使用?

编辑:

这是演示第二个问题的最小代码块:崩溃。我已经删除了所有的错误处理等。

通常在第一次/第二次迭代时应用程序崩溃。WinINet 创建的线程之一生成访问冲突:

值得注意的是,上面的地址对于用 C++(至少是 MSVC)编写的代码有特殊的意义。AFAIK,当您删除具有vtable(即-具有虚拟功能)的对象时-将其设置为上述地址。所以这是尝试调用已删除对象的虚函数。

0 投票
2 回答
1364 浏览

c++ - wininet.dll 中看似随机崩溃的原因?

我在 wininet.dll 的深处崩溃了。它试图读取零内存位置时崩溃了HTTP_REQUEST_HANDLE_OBJECT::ReleaseConnection

这是实际 DLL 中的错误,而不是由于使用不当造成的吗?

wininet!HTTP_REQUEST_HANDLE_OBJECT::ReleaseConnection+0x60
wininet!HTTP_REQUEST_HANDLE_OBJECT::CloseConnection+0x84
wininet!HTTP_REQUEST_HANDLE_OBJECT::ReadData_Fsm+0x5e8
wininet!CFsm_ReadData::RunSM+0x2e
wininet!CFsm::Run+0x39
wininet!DoFsm+0x25
wininet!HTTP_REQUEST_HANDLE_OBJECT:: ReadData+0x38
wininet!HTTP_REQUEST_HANDLE_OBJECT::HttpReadData_Fsm+0x43
wininet!CFsm_HttpReadData::RunSM+ 0x2e
wininet!CFsm::Run+0x39
wininet!DoFsm+0x25
wininet!HttpReadData+0x67
wininet!ReadFile_Fsm+0x2d
wininet!CFsm_ReadFile::bSM+
wininet!CFsm::Run+0x39
wininet!DoFsm+0x25
wininet!InternetReadFile+0x3ca

上下文是我正在尝试下载文件。我打电话

InternetReadFile (hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead);

hFile HINTERNET 句柄似乎很好(值是 0x00cc0024,这似乎是合法的) dwNumberOfBytesToRead 是 20000。

我的缓冲区大小是 131000,这也很好。

问题是我的代码在 99.9999% 的时间内都能正常工作!

0 投票
1 回答
4401 浏览

c# - 使用 wininet 设置代理设置

我在使用 wininet 设置代理用户名和密码时遇到问题。

下面的代码设置了代理,但用户名和密码失败,错误代码为“12018”

0 投票
2 回答
2134 浏览

c++ - WinINet 无法将文件下载到客户端?

我很好奇为什么我在使用此功能时遇到问题。我正在将网络上的 PNG 文件下载到目标路径。例如,将 Google 图像下载到 C: 盘:

netDownloadData(" http://www.google.com/intl/en_ALL/images/srpr/logo1w.png ", "c:\file.png");

下载后文件大小正确。没有返回错误。当我尝试打开它时,它不会显示图像。任何想法都是有帮助的。谢谢!

这是代码:

0 投票
4 回答
2697 浏览

multithreading - 从 Internet 下载文件,同时可以随时中止下载

我想在专用于下载的单独线程中从我的 Delphi 程序下载文件。

问题是主程序可以随时关闭(因此下载线程也可以随时终止)。因此,即使没有连接或服务器延迟了宝贵的几秒钟,我也需要一种方法在一两秒内终止下载线程。

你们推荐使用什么功能?

我已经尝试过 InterOpenURL/InternetReadFile 但它没有超时参数。它确实有一个异步版本,但我找不到任何可用的 Delphi 示例,我不确定异步版本是否会保护我免于挂起......

之前有人向我推荐过使用套接字,但 TClientSocket 似乎也没有超时功能。

我需要做好充分准备,因此如果用户在他/她的计算机上遇到 Internet 连接问题或网络服务器一直滞后,我的应用程序在关闭之前不会挂起。

请记住,在回答我既不想使用任何第三方组件也不想使用 Indy 时。非常感谢任何示例代码。

谢谢!

0 投票
1 回答
698 浏览

c# - IE 新会话 C# wininet?

我看过几篇关于 wininet 如何强制 Web 浏览器控件启动新会话的文章(相当于打开 IE,转到文件,然后单击新会话)。

这是正确的还是我误解了?如果可能的话,有人可以为我指出可以让我开始使用它的参考材料的方向吗?

提前致谢。

0 投票
1 回答
777 浏览

windows - WinINET 是可重入的吗?

我看到 WinHTTP 不可重入(12)。WinINET 是可重入的吗?

我们有一个 ActiveX 控件,它与 WinINET 进行同步 HTTP。如果浏览器(在 javascript 中)触发异步 http 请求(ajax)然后立即调用 ActiveX 操作(相同的 IE 进程),看起来这两个操作是交错的,可能在同一个 API 上可重入,并打破 WinINET 状态: ajax 上的 clearInterval 错误地失败了一次。我们将 EXT 用于 ajax,并且 EXT 假设 clearInterval 第一次工作。

0 投票
1 回答
2470 浏览

c# - C# wininet InternetSetOption

我正在使用如何清除 System.Windows.Forms.WebBrowser 会话数据?只要只有一个浏览器,它就可以工作。是否可以在同一个应用程序中为 2 个 Web 浏览器控件提供自己的会话?

如果是这样,我是否只需要改变

?

还是需要别的什么?

0 投票
1 回答
201 浏览

c++ - 来自应用程序的 HTTP 请求在发件人的网络/代理和我们的网络主机之间消失

我还没有太多信息可以在这里使用。我们的应用程序向我们的服务器发送一个 HTTP 查询,并且在我们迄今为止使用的所有情况下,它都运行良好。但是对于一个网络通过代理的客户端,他们的日志表明请求成功发出,但没有任何回复返回,并且我们的 Web 服务器在日志中没有显示任何关于已收到任何内容的信息(在发生故障的时间段) ,日志中的所有内容都是从安装程序内部下载 ZIP,如下所述)。对于他们网络上的任何人来说,这种情况始终如一。

一个奇怪的事情是,应用程序的安装程序发送了一个对 ZIP 文件的 HTTP 请求,它完成得很好,但是在启动应用程序时,它的第一个请求(对 PHP 文件)失败了。它们共享用于发出请求的相同基本代码,但只是发送不同的参数。我一直在试图弄清楚这两个电话的真正不同之处,它基本上可以归结为:

  • 一个是请求一个zip文件,另一个是发送参数到一个php文件;文件类型过滤?
  • 失败的那个添加了一些额外的标头参数。我会理解他们是否被代理剥离,但如果它有自定义/不受支持的标头,它会完全放弃请求吗?

这是函数调用的基本骨架结构:

我将设置一个新的构建,它将提供更多的错误检查,以确定请求的哪一部分失败以及返回了哪些错误代码。它还将取消自定义标头,以及此与安装程序之间的任何其他不一致。

我真的不太相信这些东西真的是原因,所以与此同时,我正在寻找关于可能出了什么问题的猜测,或者我应该仔细检查或注意哪些事情。我最初确信这只是他们锁定网络的过滤问题,但通过与他们的 IT 团队交谈,它发出的请求并没有被他们阻止。也许我正在做一些非标准的事情。