Blog / 阅读

微端用到的下载代码

by admin on 2014-03-31 13:39:39 in ,







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;  
}  



写评论

相关文章

上一篇:游戏微端登录器开发 几点经验

下一篇:DES加密算法详解- -

评论

写评论

* 必填.

分享

栏目

赞助商


热门文章

Tag 云