在 wininet 中使用 InternetConnect() API 后,如何判断我是不是仍然连接?
Posted
技术标签:
【中文标题】在 wininet 中使用 InternetConnect() API 后,如何判断我是不是仍然连接?【英文标题】:After using the InternetConnect() API in wininet how can I tell if I'm still connected?在 wininet 中使用 InternetConnect() API 后,如何判断我是否仍然连接? 【发布时间】:2016-06-08 15:46:39 【问题描述】:我使用 WinINet API 中的 InternetConnect() 方法。我很好地连接到我的 FTP 服务器,没有任何问题。连接后,我等待了大约 1 分钟,并且由于没有预期的活动,服务器断开了我的连接。然后我尝试发送一个文件,但我没有连接。
有没有办法“检查” FTP 连接以查看我是否仍然连接?或者有什么方法可以让我附加一个事件来告诉我什么时候断开连接?
【问题讨论】:
编写自己的方法来检查 FTP 连接:即if (!FTPConnection) throw new Exception("Exception Text")
哇,这有点含糊。 FTPConnection 是什么类型的对象?你从哪里得到它?
@jdweng 我知道有人会这么建议。 :) 我只是使用一个简单的例子来实现相同的最终结果。当有人拔掉电缆或互联网连接中断时会发生什么?如果服务器管理员强制断开连接怎么办?无论哪种方式,KeepAlive 都不是有效的解决方案。
获取状态也不行。断开电缆,客户端仍然会报告连接已关闭,也不会报告互联网是否出现故障。使用 ping 会让人更有信心,但永远不会完全有信心。
【参考方案1】:
我没有将wininet 用于FTP,我使用的是类,而不是直接使用全局函数。但我怀疑 CFtpConnection 在这方面的行为与 CHttpConnection 相同。无论如何,您可能会从我对后者的发现中学到一些东西。
CHttpConnection 似乎是一个高级抽象的连接。当我开始时,我希望它的成员函数在服务器关闭底层套接字(超时)后抛出异常。我现在知道得更好,或者至少不相信。套接字的正常关闭不会导致在这种高级 wininet 中引发异常。您可能会怀疑检查 wininet 错误代码:没有与关闭连接的服务器相对应的代码。
我对此进行了实验,发现:服务器关闭套接字(超时)被认为是正常的,不会导致抛出异常。您可以继续使用 CHttpConnection 而不必担心这一点。如果需要,它会简单地重新连接而不会提醒您。因此,一旦您调用了 GetHttpConnection 并获得了 CHttpConnection 对象,它通常会一直持续下去!
可能抛出的异常 ERROR_INTERNET_CONNECTION_ABORTED 和 ERROR_INTERNET_CONNECTION_RESET 是由异常情况引起的,例如 f.ex。代理服务器崩溃或有人不小心将电源插头拔到调制解调器上。服务器因超时而关闭套接字被认为是正常的,并且对 wininet 类的用户是透明的。
所以暂定的结论是你不必担心连接被服务器关闭。如果发生这种情况,CHttpConnection 将在后台重新连接,您将不会被打扰。您可以假装连接始终保持打开状态 - 对于 wininet 类的用户来说似乎是这样。
考虑以下实验。打开一个连接,然后每分钟发送一次请求。一旦抛出异常,该函数就会返回。但如果不是,那么它会永远循环。我在两个不同的网站上尝试过: 永远不会抛出异常!尽管请求之间有一整分钟的不活动。
int httpclient::test(string host)
int flags = INTERNET_FLAG_RELOAD;
int port = INTERNET_DEFAULT_HTTP_PORT;
CHttpConnection *connection = session.GetHttpConnection(host.cstring(),flags,port);
int secs = 0;
while (true)
CHttpFile *fil;
try
fil = connection->OpenRequest(CHttpConnection::HTTP_VERB_HEAD, "index.htm",
0,1,0, "HTTP/1.1", flags);
catch (CInternetException *exc)
connection->Close();
int feil = exc->m_dwError;
exc->Delete();
return -feil;
fil->AddRequestHeaders("Connection: Keep-Alive");
try
fil->SendRequest();
catch (CInternetException *exc)
connection->Close();
int feil = exc->m_dwError;
exc->Delete();
return feil;
fil->Close();
Sleep(60 * 1000);
secs += 60;
printf("%u seconds passed\n", secs);
return 0;
对这一切持保留态度。 wininet 的文档记录很差,我所知道的只是实验教给我的。
【讨论】:
以上是关于在 wininet 中使用 InternetConnect() API 后,如何判断我是不是仍然连接?的主要内容,如果未能解决你的问题,请参考以下文章
在 wininet 中使用 InternetConnect() API 后,如何判断我是不是仍然连接?