« 前一篇:RemovePath
后一篇:DebugString »

UrlDownloadData @ 2/10/2006

技术类
下载一个URL并获取其内容。
// socket Version
HRESULT UrlDownloadData(LPCTSTR szUrl, BYTE* &lpszData, DWORD &dwSize) {
    CHAR szServer[256];
    CHAR szUri[512];
    UINT index = 0;
    if(strnicmp(szUrl, "http://", 7) != 0) {
        return E_FAIL;
    }
    for(index = 7; index < strlen(szUrl); index ++) {
        if(szUrl[index] == '/') {
            break;
        }
    }
    if(index == strlen(szUrl)) {
        strcpy(szServer, szUrl + 7);
        strcpy(szUri, "/");
    } else {
        strncpy(szServer, szUrl + 7, index - 7);
        szServer[index - 7] = '\0';
        strcpy(szUri, szUrl + index);
    }
   
    WSADATA wsaData;
    if(0 != WSAStartup(MAKEWORD(2,2),&wsaData)) {
        return E_FAIL;
    }
    SOCKET sockConn = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(INVALID_SOCKET == sockConn) {
        WSACleanup();
        return E_FAIL;
    }
    struct hostent *hostServer;

    if(INADDR_NONE == inet_addr(szServer)) {
        hostServer=gethostbyname(szServer);
    } else {
        ULONG ulAddr=inet_addr(szServer);
        hostServer=gethostbyaddr((char*)&ulAddr,sizeof(ulAddr),AF_INET);
    }
    if(hostServer==NULL) {
        closesocket(sockConn);
        WSACleanup();
        return E_FAIL;
    }
    struct sockaddr_in saServer;
    saServer.sin_addr.s_addr=*((unsigned long*)hostServer->h_addr);
    saServer.sin_family=AF_INET;
    saServer.sin_port=htons(80);
    if(connect(sockConn,(struct sockaddr*)&saServer,sizeof(saServer))) {
        closesocket(sockConn);
        WSACleanup();
        return E_FAIL;
    }
    BYTE buff[1024];
    strcpy((LPSTR)buff, "GET ");
    strcat((LPSTR)buff, szUri);
    strcat((LPSTR)buff, "\r\n\r\n");

    if(SOCKET_ERROR == send(sockConn, (LPSTR)buff, strlen((LPSTR)buff), 0)) {
        D("Failed to send request.");W
        closesocket(sockConn);
        WSACleanup();
        return E_FAIL;
    }
    lpszData = NULL;
    dwSize = 0;
    int bytesRecv = SOCKET_ERROR;
    while(TRUE) {
        bytesRecv = recv(sockConn, (LPSTR)buff, 1024, 0);
        if(bytesRecv == 0) {
            break;
        } else if(bytesRecv == SOCKET_ERROR) {
            delete[] lpszData;
            lpszData = NULL;
            dwSize = 0;
            break;
        }
        BYTE* lpTemp = lpszData;
        lpszData = new BYTE[dwSize + bytesRecv];
        memcpy(lpszData, lpTemp, dwSize);
        memcpy(lpszData + dwSize, buff, bytesRecv);
        dwSize += bytesRecv;
        delete[] lpTemp;
    }
    closesocket(sockConn);
    WSACleanup();
    return S_OK;
}

// wininet version
HRESULT UrlDownloadData(LPCTSTR szUrl, BYTE* &lpszData, DWORD &dwSize) {
    URL_COMPONENTS urlComponents;
    memset(&urlComponents, 0, sizeof(urlComponents));
    urlComponents.dwStructSize = sizeof(urlComponents);
    urlComponents.dwHostNameLength = 1;
    urlComponents.dwUrlPathLength = 1;
    BOOL bSuccess = InternetCrackUrl((LPCSTR)szUrl, 0, 0, &urlComponents);
    if(!bSuccess) {
        return E_FAIL;
    }
    CHAR szHostName[256];
    strncpy(szHostName, urlComponents.lpszHostName, urlComponents.dwHostNameLength);
    szHostName[urlComponents.dwHostNameLength] = 0;
    CHAR szUrlPath[1024];
    strncpy(szUrlPath, urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
    szUrlPath[urlComponents.dwUrlPathLength] = 0;
    USHORT nPort = urlComponents.nPort;

    HINTERNET hSession = InternetOpen("MSIE 2.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if(hSession != NULL) {
        HINTERNET hConnection = InternetConnect(hSession, _T(szHostName), nPort, NULL, NULL, urlComponents.nScheme, 0, 0);
        if(hConnection != NULL) {
            static LPCTSTR* lpszAcceptTypes = NULL;
            static LPCTSTR lpszMethod = "GET";
            HINTERNET hRequest = HttpOpenRequest(hConnection, lpszMethod, _T(szUrlPath), HTTP_VERSION, NULL, lpszAcceptTypes,
                INTERNET_FLAG_DONT_CACHE, NULL);
            if(hRequest != NULL) {
                CHAR* szHeader = NULL;
                CHAR* szPost = NULL;
                BOOL bSend = ::HttpSendRequest(hRequest, szHeader,0, szPost,0);
                if(!bSend) {
                    InternetCloseHandle(hRequest);
                    InternetCloseHandle(hConnection);
                    InternetCloseHandle(hSession);
                    return E_FAIL;
                }
               
                CHAR bufStatusCode[80];
                DWORD dwStatusSize = sizeof(bufStatusCode);
                if(FALSE == ::HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE,
                    &bufStatusCode, &dwStatusSize, NULL)) { //获取返回状态码
                    InternetCloseHandle(hRequest);
                    InternetCloseHandle(hConnection);
                    InternetCloseHandle(hSession);
                    return E_FAIL;
                }
                UINT nStatusCode = (UINT)atol(bufStatusCode);
                //判断状态码是不是 200
                if(HTTP_STATUS_OK != nStatusCode) {
                    InternetCloseHandle(hRequest);
                    InternetCloseHandle(hConnection);
                    InternetCloseHandle(hSession);
                    return FALSE;
                }
                // Get the length of the file.
                char bufContentLength[32];
                DWORD dwLengthSize = sizeof(bufContentLength);
                if(FALSE == ::HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH,
                    bufContentLength, &dwLengthSize, NULL)) { // 取文件长度
                    InternetCloseHandle(hRequest);
                    InternetCloseHandle(hConnection);
                    InternetCloseHandle(hSession);
                    return E_FAIL;
                }
                DWORD dwFileSize = (DWORD)atol(bufContentLength);
               
                BYTE*    lpszBuff = NULL;
                DWORD    dwBuff = 1024;
                DWORD    dwRead;
                BOOL      bDownload = TRUE;

                lpszData = new BYTE[dwFileSize];
                dwSize = 0;
                do {
                    if(!InternetQueryDataAvailable(hRequest,&dwBuff,0,0)) {
                        if(lpszBuff != NULL) {
                            delete[] lpszBuff;
                        }

                        InternetCloseHandle(hRequest);
                        InternetCloseHandle(hConnection);
                        InternetCloseHandle(hSession);

                        delete[] lpszData;
                        lpszData = NULL;
                        dwSize = 0;

                        return E_FAIL;
                    } else {
                        lpszBuff = new BYTE[dwBuff];
                        if(!InternetReadFile(hRequest,(LPVOID)lpszBuff,dwBuff,&dwRead)) {
                            delete[] lpszBuff;
                            InternetCloseHandle(hRequest);
                            InternetCloseHandle(hConnection);
                            InternetCloseHandle(hSession);

                            delete[] lpszData;
                            lpszData = NULL;
                            dwSize = 0;

                            return E_FAIL;
                        } else {
                            if(dwRead == 0) {
                                delete[] lpszBuff;
                                break;
                            }
                            DWORD dwCurrent = dwSize;
                            dwSize += dwRead;
                            if(dwSize <= dwFileSize) {
                                memcpy(lpszData + dwCurrent, lpszBuff, dwRead);
                                delete[] lpszBuff;
                            } else {
                                delete[] lpszBuff;
                                InternetCloseHandle(hRequest);
                                InternetCloseHandle(hConnection);
                                InternetCloseHandle(hSession);

                                delete[] lpszData;
                                lpszData = NULL;
                                dwSize = 0;

                                return E_FAIL;
                            }
                        }
                    }
                } while(bDownload);
                InternetCloseHandle(hRequest);
                InternetCloseHandle(hConnection);
                InternetCloseHandle(hSession);
                return S_OK;
            } else {
                InternetCloseHandle(hConnection);
                InternetCloseHandle(hSession);
            }
        } else {
            InternetCloseHandle(hSession);
        }
    }
    return E_FAIL;
}

BOOL UrlDownloadFile(LPCTSTR szUrl, LPCTSTR szFile) {
    LPBYTE pData = NULL;
    DWORD dwSize = 0;
    HRESULT hRet = UrlDownloadData(szUrl, pData, dwSize);
    if(SUCCEEDED(hRet) && dwSize > 1024) {//读取文件
        OFSTRUCT ofs;
        HANDLE hFile = (HANDLE)OpenFile(szFile, &ofs, OF_CREATE | OF_WRITE | OF_SHARE_EXCLUSIVE);
        if(hFile) {
            DWORD dwWritten;
            WriteFile(hFile, pData, dwSize, &dwWritten, NULL);
            CloseHandle(hFile);
            delete[] pData;
            return TRUE;
        }
    }
    delete[] pData;
    return FALSE;
}
发布于 2/10/2006 12:00:55 | 评论:0

看帖要回帖...

categories
archives
links
statistics
  • 网志数:1168
  • 评论数:2011