读书人

微端用到的上载代码

发布时间: 2012-08-10 12:19:33 作者: rapoo

微端用到的下载代码



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







读书人网 >互联网

热点推荐