Socket 模拟 Get 请求 ip138 ,获取外网IP

使用 Socket 的原因:

使用 CInternetSession , CHttpFile  请求某些查询IP的网站时,发现有迟钝刷新现象,没有及时刷新外网IP(使用VPN连接)

而 Socket 请求却没有这个现象,有可能是网站本身针对的原因,也有可能是 CInternetSession , CHttpFile 有缺陷。

 

使用 Socket 的缺点:

有时候会发生 Socket 相关的错误, 尤其在网络情况不好的时候, 丢包或者延迟高的情况。

解决方法:

为了不返回错误的信息回去,误认为是掉线了, 可设定一个超时时间参数,当发生错误时,检测所用时间是否超时,否则继续循环,

当超出 限定时间, 方可认为是掉线了。(或在上层调用时,若发生错误 限时检测)

 


CString GetCurIPAddress()
{
    SOCKET hsocket;
    SOCKADDR_IN saServer;
    WSADATA     wsadata;
    LPHOSTENT lphostent;
    int     nRet;
    char*   host_name="city.ip138.com";

    char*   reqHead="GET http://city.ip138.com/ip2city.asp HTTP/1.1\r\n"   //此为要发送的数据包
        "Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*\r\n"
        "Accept-Language: zh-CN\r\n"
        "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)\r\n"
        "Content-Type: application/x-www-form-urlencoded\r\n"
        "Accept-Encoding: gzip, deflate\r\n"
        "Host: city.ip138.com\r\n"
        "Content-Length: 0\r\n"
        "Connection: Keep-Alive\r\n\r\n";
    
    // 初始化套接字
    if(WSAStartup(MAKEWORD(2,2), &wsadata))
    {
        OutputDebugString("初始化错误");
        Sleep(2000);
        return GetCurIPAddress();
    }
    
    lphostent = gethostbyname(host_name);
    if(lphostent == NULL)
    {
        OutputDebugString("lphostent为空!");
        Sleep(2000);
        return GetCurIPAddress();
    }
    
    hsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    saServer.sin_family = AF_INET;
    saServer.sin_port = htons(80);
    saServer.sin_addr = *((LPIN_ADDR)*lphostent->h_addr_list);

    // SOCKET连接
    nRet = connect(hsocket, (LPSOCKADDR)&saServer, sizeof(saServer));
    if(nRet == SOCKET_ERROR)
    {
        OutputDebugString("建立连接时出错!");
        closesocket(hsocket);
        Sleep(2000);
        return GetCurIPAddress();
    }

    // SOCKET发送
    nRet = send(hsocket, reqHead, strlen(reqHead), 0);
    if(nRet==SOCKET_ERROR)
    {
        OutputDebugString("发送数据包时出错!");
        closesocket(hsocket);
        Sleep(2000);
        return GetCurIPAddress();
    }
    Sleep(1000);
    //char   Dest[1024] = {0};
    CString strHtml;
    
    do
    {
        // 接收返回数据包
        nRet = recv(hsocket, strHtml.GetBuffer(1024), 1024, 0);
        strHtml.ReleaseBuffer();
        if (nRet == 0 || nRet == WSAECONNRESET)
        {
            OutputDebugString("Connection Closed");
            break;
        }
        else if (nRet == SOCKET_ERROR)
        {
            OutputDebugString("socket error");
            break;
        }
        else
        {
            //OutputDebugString(strHtml);
            if (strHtml.GetLength() < 1024 || strHtml.Find("</html>") >= 0)
            {
                break;
            }
        }
    }while (nRet > 0);
    closesocket(hsocket);

    int index = strHtml.Find("[");
    if (index < 0)
    {
        OutputDebugString("找不到特征索引 1 GetCurIPAddress");
        Sleep(2000);
        return GetCurIPAddress();
    }

    strHtml = strHtml.Mid(index+1).GetBuffer(NULL);
    if (strHtml.GetLength() < 1)
    {
        OutputDebugString("截取ip失败1    GetCurIPAddress");
        Sleep(2000);
        return GetCurIPAddress();
    }

    index = strHtml.Find("]");
    if (index < 0)
    {
        OutputDebugString("找不到特征索引 2 GetCurIPAddress");
        Sleep(2000);
        return GetCurIPAddress();
    }

    strHtml = strHtml.Mid(0, index).GetBuffer(NULL);
    if (strHtml.GetLength() < 1)
    {
        OutputDebugString("截取ip失败2    GetCurIPAddress");
        Sleep(2000);
        return GetCurIPAddress();
    }
    
    return strHtml;
}

posted on 2015-08-08 17:32  伊扎洛  阅读(562)  评论(0)    收藏  举报

导航