微端用到的下載代碼

來源:互聯網
上載者:User

const INT RECV_BUFFER_LEN = 1024;
//////////////////////////////////////////////////////////////////////  
// Construction/Destruction  
//////////////////////////////////////////////////////////////////////  
DLRequest::DLRequest()  
{  

}  

DLRequest::~DLRequest()  
{  

}  

//*******************************************************************************************************  
// GetHostAddress:   
//                  Resolve using DNS or similar(WINS,etc) the IP   
//                   address for a domain name such as www.wdj.com.   
//*******************************************************************************************************  
DWORD DLRequest::GetHostAddress(LPCSTR host)  
{  
struct hostent *phe;  
char *p;  

phe = gethostbyname( host );  

if(phe==NULL)  
return 0;  

p = *phe->h_addr_list;  
return *((DWORD*)p);  
}  

//*******************************************************************************************************  
// SendString:   
//                  Send a string(null terminated) over the specified socket.  
//*******************************************************************************************************  
void DLRequest::SendString(SOCKET sock,LPCSTR str)  
{  
send(sock,str,strlen(str),0);  
}  

//*******************************************************************************************************  
// ValidHostChar:   
//                  Return TRUE if the specified character is valid  
//                      for a host name, i.e. A-Z or 0-9 or -.:   
//*******************************************************************************************************  
BOOL DLRequest::ValidHostChar(char ch)  
{  
return( isalpha(ch) || isdigit(ch)  
|| ch=='-' || ch=='.' || ch==':' );  
}  

void DLRequest::ParseURL(std::string url,LPSTR protocol,int lprotocol, LPSTR host,int lhost,LPSTR request,int lrequest,int *port)
{  
char *work,*ptr,*ptr2;  

*protocol = *host = *request = 0;  
*port=80;  

work = _strdup(url.c_str());  
_strupr_s(work, strlen(work) +1);  

ptr = strchr(work,':');                         // find protocol if any  
if(ptr!=NULL)  
{  
*(ptr++) = 0;  
lstrcpyn(protocol,work,lprotocol);  
}  
else 
{  
lstrcpyn(protocol,"HTTP",lprotocol);  
ptr = work;  
}  

if( (*ptr=='/') && (*(ptr+1)=='/') )            // skip past opening /'s   
ptr+=2;  

ptr2 = ptr;                                     // find host  
while( ValidHostChar(*ptr2) && *ptr2 )  
ptr2++;  

*ptr2=0;  
lstrcpyn(host,ptr,lhost);  

lstrcpyn(request,url.c_str() + (ptr2-work),lrequest);   // find the request  

ptr = strchr(host,':');                         // find the port number, if any  
if(ptr!=NULL)  
{  
*ptr=0;  
*port = atoi(ptr+1);  
}  

free(work);  
}  

int DLRequest::RequestHttpDL(std::string url)  
{  
WSADATA         WsaData;  
 
 
char            protocol[20];
char host[256];
 
int             l,port,chars,err;  

 

char request[256] = { 0 };

ParseURL(url,protocol,sizeof(protocol),host,sizeof(host),       // Parse the URL  
request,sizeof(request),&port);  
if(strcmp(protocol,"HTTP"))  
return 1;  

err = WSAStartup (0x0101, &WsaData);                            // Init Winsock  
if(err!=0)  
return 1;  

SOCKET sock = socket (AF_INET, SOCK_STREAM, 0);  
if (sock == INVALID_SOCKET)  
{  
return 1;  
}  

SOCKADDR_IN     sin; 
sin.sin_family = AF_INET;                                       //Connect to web sever  
sin.sin_port = htons( (unsigned short)port );  
sin.sin_addr.s_addr = GetHostAddress(host);  

if( connect (sock,(LPSOCKADDR)&sin, sizeof(SOCKADDR_IN) ) )  
{  

return 1;  
}  

if( !*request )  
lstrcpyn(request,"/",sizeof(request));  

//格式化要求標頭
std::string strHeadSend("GET ");
strHeadSend += request;
strHeadSend += " HTTP/1.0\r\n";
strHeadSend += "Accept: */*\r\n";
strHeadSend += "Accept-Language: en-us\r\n";
strHeadSend += "Host: ";
strHeadSend += host;
strHeadSend += "\r\n\r\n";

//發送要求標頭
SendString( sock, strHeadSend.c_str() );

// MemBuffer       headersBuffer,messageBuffer;  
// 
// MemBufferCreate(&headersBuffer );  
chars = 0;  
BOOL            done;  
done = FALSE;  

char            buffer[RECV_BUFFER_LEN] = { 0 };
int nPosition = 0;
while(!done)  
{  
l = recv(sock,buffer + nPosition,1,0);  
if(l<0)  
done=TRUE;  

switch(*(buffer+nPosition))  
{  
case '\r':  
break;  
case '\n':  
if(chars==0)  
done = TRUE;  
chars=0;  
break;  
default:  
chars++;  
break;  
}  
nPosition++;
}  

//獲得狀態代碼
//200 OK
用戶端請求成功
//400 Bad Request
用戶端有語法錯誤,不能被伺服器所理解
//401 Unauthorized
請求未經授權
//403 Forbidden
伺服器收到請求,但是拒絕提供服務
//404 Not Found
請求資源不存在,可能輸入了錯誤的URL
//500 Internal Server Error 伺服器發生了不可預期的錯誤
//503 Server Unavailable
伺服器當前不能處理用戶端的請求,一段時間後可能恢複正常
CHAR szHttpVer[ 32 ] = { 0 };
INT nStatusCode = 0; 
sscanf( buffer, "%s %d", szHttpVer, &nStatusCode );

if( 200 != nStatusCode )
{
if( 403 == nStatusCode || 503 == nStatusCode ) 
{

}
else
{
return 1;//失敗
}
}
//獲得檔案長度
INT nFileLength = 0;
char* pFindCL = strstr( buffer, "Content-Length:" );
if( pFindCL != NULL )
{
CHAR szTemp[ 32 ] = { 0 };
sscanf( pFindCL, "%s %d", szTemp, &nFileLength );
}

//得到路徑
char szDirectory[ MAX_PATH ] = { 0 };
GetCurrentDirectory( MAX_PATH, szDirectory );

std::string strFileName = szDirectory;
strFileName += request;
std::replace( strFileName.begin(), strFileName.end(), '\\', '/' );

//獲得原始檔案名稱
std::string strOrigFileName = strFileName;
// int findPos = strFileName.find_last_of( "/" );
// if( findPos != string::npos )
// {
// strOrigFileName = strFileName.substr( findPos + 1 );

// }

strFileName += ".tmp";
//檔案名稱修改成一個臨時檔案名稱,下載完畢後還原

FILE* pFile = NULL;
fopen_s(&pFile, strFileName.c_str(), "wb" );
//開啟一個檔案,寫,如果檔案存在,則清空
if( !pFile )
{
return 1;
}

INT nRecvedSize = 0;
//已經接收的數量
INT nPos = 0;
//位移
while( TRUE )
{
INT nRecv = recv( sock, buffer + nPos, RECV_BUFFER_LEN - nPos, 0 );
if( nRecv > 0 )
{
nRecvedSize += nRecv;
nPos += nRecv;

if( nPos >= RECV_BUFFER_LEN && nRecvedSize < nFileLength )//BUFF滿了,但檔案沒有接受完畢
{
//內容寫到檔案中
fwrite( buffer, RECV_BUFFER_LEN, 1, pFile );
nPos = 0;
}
else if( nRecvedSize >= nFileLength )//檔案接收完畢
{
//檔案接收完畢,儲存內容
fwrite( buffer, nPos, 1, pFile );
fclose( pFile );
//修改檔案名稱
rename( strFileName.c_str(), strOrigFileName.c_str() );
break;
}
}
else if( 0 == nRecv )
{
//socket關閉
break;
}
else
{
int nErrCode = WSAGetLastError();
break;
}
}

closesocket(sock);                                        

return 0;  
}  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.