- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
文档指出可以多次调用 InternetOpen 而不会出现任何问题。我的问题是我应该多次调用 InternetCloseHandle 返回的句柄吗?
例如,我有一个名为 CAPIRequestContext
的类,它有一个由 InternetOpen 返回的句柄。我的每一个请求都有它自己的拷贝。现在,我在析构函数中调用了 InternetCloseHandle,所以它被调用了多次。
我想知道以下是否会导致问题:线程 A 创建一个 CAPIRequestObject
,它调用 InternetOpen 并存储句柄。线程 B 做同样的事情,但在线程 A 退出之前超出范围,因此线程 B 在它自己的 CAPIRequestObject
中调用析构函数,它在由返回的句柄上调用 InternetCloseHandle
互联网开放。
我应该在我的类的析构函数中删除对 InternetCloseHandle 的调用吗?至少对于 InternetHandle?我假设我应该为 HttpOpenRequest 返回的句柄调用 InternetCloseHandle。
我对 InternetConnect 返回的句柄有类似的疑问。这些句柄是共享的吗?
这是一些示例代码,减去一些我认为与问题无关的外部代码:
class CAPIClient;
class CAPIRequest
{
public:
CAPIRequestContext()
{
m_hConn = NULL;
m_hInternet = NULL;
m_hRequest = NULL;
}
~CAPIRequestContext()
{
if (m_hRequest) InternetCloseHandle(m_hRequest);
if (m_hConn) InternetCloseHandle(m_hConn);
if (m_hInternet) InternetCloseHandle(m_hInternet);
}
bool Init(const CAPIClient &client, const std::string &uri, const std::string &method)
{
ATLASSERT(!(m_hInternet || m_hConn || m_hRequest));
if (m_hInternet || m_hConn || m_hRequest) throw std::exception("Cannot init request more than once.");
bool success = false;
m_AuthToken = *client.m_pAuthToken;
URI = uri;
m_hInternet = InternetOpen("MyApp", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
DWORD requestTimeout = 60 * 1000; // Set timeout to 60 seconds instead of 30
if (m_hInternet)
{
InternetSetOption(m_hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &requestTimeout, sizeof(requestTimeout));
m_hConn = InternetConnect(m_hInternet, (LPSTR)client.m_host.c_str(), client.m_port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)this);
if (m_hConn) {
m_hRequest = HttpOpenRequest(m_hConn, method.c_str(), uri.c_str(), "HTTP/1.1", NULL, NULL, client.GetOpenRequestFlags(), 0);
}
if (m_hRequest)
{
success = true;
}
}
return success;
}
}
// There are additional calls like
// SendRequest
// GetData
// GetFullResponse
private:
// Added these methods to make sure I'm not copying the handles
enter code here
CAPIRequestContext(const CAPIRequestContext &other) = delete;
CAPIRequestContext& operator=(const CAPIRequestContext& other) = delete;
private:
HINTERNET m_hInternet;
HINTERNET m_hConn;
HINTERNET m_hRequest;
}
最佳答案
The documentation states that InternetOpen can be called multiple times without any issues. My question though is should I be calling InternetCloseHandle on handle returned by it multiple times?
是的,如 InternetOpen()
中所述文档:
After the calling application has finished using the
HINTERNET
handle returned byInternetOpen
, it must be closed using theInternetCloseHandle
function.
For example, I have a class I call
CAPIRequestContext
, which has a handle which is returned byInternetOpen
. Each one of my requests has it's own copy. Right now, I callInternetCloseHandle
in the destructor, so it gets called multiple times.
如果类的每个实例都调用 InternetOpen()
,或者以其他方式获得唯一的 HINTERNET
的所有权,那将是一个正确的实现。
但是,请注意此类需要实现 Rule of Three .基本上,如果您必须提供析构函数来释放资源,您还需要提供复制构造函数和复制赋值运算符。
但是,您不能在同一个 HINTERNET
上多次调用 InternetCloseHandle()
,因此您不能使用多个 CAPIRequestContext
相同的 HINTERNET
并且它们都调用 InternetCloseHandle()
1。因此,您的复制构造函数和复制赋值运算符必须:
从正在复制的源 CAPIRequestContext
获取 HINTERNET
的所有权。
完全禁用以防止将一个 CAPIRequestContext
复制到另一个。
在您的情况下,我会选择 #2。
1:您需要一个实例标志,指示哪个实例可以调用它,哪些不能。但这不是好的类设计。如果您需要共享一个 HINTERNET
,您应该改为实现引用计数语义,例如由 std::shared_ptr
提供的。
I'm wondering if the following could cause issues: Thread A creates a CAPIRequestObject which calls InternetOpen and stores the handle. Thread B does the same, but then goes out of scope before Thread A exits, so Thread B calls the destructor in it's own CAPIRequestObject, which calls InternetCloseHandle on the handle returned by InternetOpen.
这是绝对安全的,前提是每个 CAPIRequestObject
都有自己的 HINTERNET
。
Should I remove the call to InternetCloseHandle in the destructors of my class?
不,如果每个类实例都拥有一个唯一的 HINTERNET
。
I assume I should call InternetCloseHandle for the handle returned by HttpOpenRequest.
是的,如 HttpOpenRequest()
中所述文档:
After the calling application has finished using the
HINTERNET
handle returned byHttpOpenRequest
, it must be closed using theInternetCloseHandle
function.
I have similar questions regarding the handle returned by InternetConnect. Are these handles shared?
每个 HINTERNET
都必须单独关闭。
关于c++ - WinInet 和 InternetOpen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37666668/
我正在寻找一个简单的函数,它能够将来自 Internet 的文本或二进制文件读入 string 多变的。 令人难以置信的是,我在网络上找不到任何内容,只有所有 WinInet 的低级描述。在 MQL
我有以下代码: #include #include #include #include #include using namespace std; int main(int argc, ch
我正在使用 wininet 连接到服务器。一切正常,上传,下载,列出命令等......因此,我有一个小错误,我不知道它来自哪里。错误是某些包含超过 100 个文件(例如图像)的服务器文件夹没有全部列出
我正在使用 WinInet 和 InternetOpenUrl 下载一个文件...正在运行。但我想监控进度,所以我尝试添加一个回调函数,但由于某种原因它从未被调用过...... 代码: void CA
我对 C++ 编程还很陌生,所以请多多包涵。我正在尝试创建一个用于教育目的的 ftp 客户端,做了一些研究并决定尝试一下 Wininet,并发现了一些在线教程: 以此为例: #include #in
我有一个将网页下载到文本文件的功能 #include #include #include #include #include #pragma comment(lib, "WinINet.li
我很好奇为什么我在使用此功能时遇到问题。我正在将网络上的 PNG 文件下载到目标路径。例如下载谷歌图片到C:盘: netDownloadData("http://www.google.com/intl
我已经为 Internet Explorer 编写了一个 BHO,它 Hook WinInet 以修改来自 IE 的一些 HTTP 请求,方法是将它们重定向到内部服务器。 当我在 IE 中打开前 3
我正在试验我的 .NET 客户端和服务器之间的缓存。在 WinInet 决定缓存结果之前,我看到一个看似随机的端点命中数。 .NET 客户端使用 HttpWebRequest 发出请求: HttpWe
我发现 WinHTTP 不可重入(1、2)。 WinINET 是可重入的吗? 我们有一个与 WinINET 同步 HTTP 的 ActiveX 控件。如果浏览器(在 javascript 中)触发一个
相关 How to send a HTTP POST Request in Delphi using WinInet api : 我如何提出发布请求并跟踪进度? 这不起作用(检查评论): proced
iam 使用 wininet 下载图像并将其保存到内存流这是我的程序 procedure DownloadToStream(const Url: string; ms: TMemoryStream);
我们使用 WinInet 和 Delphi 通过 HTTPS 进行通信。WinInet 中是否有一个函数可以返回 session 中协商的协议(protocol),即 TLS1.1、TLS 1.2 等
我有一个应用程序,它大量使用 Wininet 函数从互联网获取一些数据。有时我会收到非常奇怪的与句柄相关的错误消息: Internal error in ConnectToHost when tryi
我从第三方网站获得了以下源代码,解释了如何使用 WinInet 从互联网下载文件。我对 API 不太熟悉,我查看了 WinInet 单元,但没有看到任何我需要的 API 调用。 我正在做的是添加报告文
我在 wininet.dll 深处遇到崩溃。尝试读取 HTTP_REQUEST_HANDLE_OBJECT::ReleaseConnection 中的零内存位置时崩溃了 这是实际 DLL 中的错误,而
我正在尝试检测 ftp 服务器何时关闭我在应用程序中打开的连接。我正在使用 WinInet 功能。 我发现了一些使用 InternetSetStatusCallback 函数的示例。我实现了一个回调函
我编写了一个使用 WinInet 库的程序。该程序每天运行约 8-12 小时。首先它连接到互联网,然后它使用 FTP 下载/上传文件。之后它开始一个循环,在不同的时间间隔启动最多两个线程。两个线程都在
我正在尝试连接并确保我们设计的仪器提供的网络服务器上存在各种页面。我正在尝试使用 WinInet 命令通过 C++ Win32 执行此操作。 我很高兴我已经通过 HTTP 正确连接到网络服务器: hI
我正在尝试使用 C++ 中的 WinHTTP 获取文件的内容。该文件是一个 XML 文件,由服务器上的可执行文件生成。 用于初始化、连接甚至读取指定服务器地址上的文件的代码正在运行。 // Conne
我是一名优秀的程序员,十分优秀!