在wininet中使用InternetConnect()API后如何判断我是否仍然连接?

时间:2016-06-08 15:46:40

标签: c# ftp wininet

我使用WinINet API中的InternetConnect()方法。我连接到我的FTP服务器没问题。连接后,我等待大约1分钟,服务器因为没有预期的活动而断开连接。然后我尝试发送文件,但我没有连接。

有没有办法“检查”FTP连接,看看我是否仍然连接?或者,当我断开连接时,是否有某种方式让我附上一个事件来告诉我?

1 个答案:

答案 0 :(得分:0)

我还没有将wininet用于FTP,我使用的是类,而不是直接使用全局函数。但我怀疑CFtpConnection在这方面的行为与CHttpConnection相同。无论如何,你可能从我发现的后者中学到一些东西。

CHttpConnection似乎是一个高级和抽象级别的连接。当我开始时,我希望它的成员函数在服务器关闭底层套接字时抛出异常(用于超时)。我现在知道更好或者至少相信不然。正常关闭套接字不会导致在这个高级别的优雅wininet中抛出异常。您可能会怀疑检查wininet错误代码:没有与已关闭连接的服务器对应的代码。

我对此进行了实验并发现:关闭套接字的服务器(用于超时)被认为是正常的,并且不会引发异常。你可以继续使用CHttpConnection而不用担心这个问题。如果需要,它将简单地重新连接,而不会提醒您。所以一旦你调用了GetHttpConnection并获得了你的CHttpConnection对象,它通常会永远持续下去!

可能引发的异常ERROR_INTERNET_CONNECTION_ABORTED和ERROR_INTERNET_CONNECTION_RESET是由异常条件引起的,f.ex。代理服务器崩溃或有人意外将电源插头拔进调制解调器。关闭套接字超时的服务器被认为是NORMAL,对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的记录很少,我所知道的只是实验告诉我的。