본문 바로가기

Native/C++

웹서버에서 파일 다운로드

[code]
bool DownloadFile( const char* IP, const char* URL, const char* FileName )
IP : 웹서버의 ip. ex) 10.1.1.1
URL : 다운로드받을 파일의 URL. ex) /image/oh.jpg
FileName : 저장시 사용할 파일명. ex) c:\oh.jpg
[/code]
[code]
////////////////////////////////////////////////////////////////////////////
// DownloadFile.cpp

#include <string>
#include <fstream>
#include <afxsock.h>

using namespace std;

bool DownloadFile( const char* IP, const char* URL, const char* FileName )
{
    string Request;
    int nRead, nContentRead=0, nContent=1;
    char szTmp[4097], *psztmp;
    bool bContent=false;
    ofstream ofs;

    Request = "GET ";
    Request += URL;
    Request += " HTTP/1.1\r\n";
    Request += "Host: ";
    Request += IP;
    Request += "\r\n\r\n"; // 2개의 CRLF 로 message-header의 끝을 구분한다.

    WSADATA wsaData;
    CSocket sock;

    WSAStartup( MAKEWORD( 2, 2 ), &wsaData );

    if ( sock.Create() == 0 ) return false;
    if ( sock.Connect( IP, 80 ) == 0 ) return false;
    if ( sock.Send( Request.c_str(), Request.length() ) == SOCKET_ERROR ) return false;

    ofs.open( FileName, ios_base::out | ios_base::trunc | ios_base::binary );

    do
    {
        nRead = sock.Receive( szTmp, 4096 );

        if ( nRead == 0 ) // 메시지를 다 받았으면
            break;
        if ( nRead == WSAEWOULDBLOCK ) // sub-network fail
            break;

        szTmp[nRead] = 0;

        if ( bContent ) // message-body 부분을 받고있을 때
        {
            nContentRead += nRead;
            ofs.write( szTmp, nRead );
        }
        else // message-header 부분을 받고 있을 때
        {
            // Content-Length == message-body의 길이
            if ( (psztmp = strstr( szTmp, "Content-Length:" )) != NULL )
                nContent = atoi( psztmp+16 );

            if ( ( psztmp = strstr( szTmp, "\r\n\r\n") ) != NULL) // message-header과 message-body의 경계(4BYTE)
            {
                bContent = true;
                nContentRead = nRead - (psztmp+4 - szTmp); // 받은 부분 중
                message-header 부분과 경계를 제외

                ofs.write( psztmp+4, nContentRead );
            }
        }

    }
    while ( nContentRead < nContent ); // 다운 받은 message-body 부분이 Content-Length 와 같아질때 까지

    ofs.close();
    sock.Close();
    WSACleanup();

    return true;
}
[/code]

'Native > C++' 카테고리의 다른 글

lotto KeyGen  (0) 2013.10.02
첫 페이지 으흐흐  (0) 2013.10.02
생성자, 소멸자의 특징  (0) 2013.10.02
액세스 권한 지정  (0) 2013.10.02
구문강조  (0) 2013.10.02