/*******************************************************************************
文件名称 : HttpXml.cpp 源文件
作 者 : 杨治明
创建时间 : 2010-11-3 15:35:37
文件描述 :
版权声明 : Copyright (C) 2008-2010 vansinfo
修改历史 : 杨治明 2010-11-3 1.00 初始版本
*******************************************************************************/
#include "StdAfx.h"
#include ".\httpxml.h"
char ReceiveBuffer[MAX_XML_SIZE]= {0};//接受最大数据
#define GET_HOST_PORT(protocol,port) ( (port) ? port : (!stricmp("http",protocol)) ? 80 : (!stricmp("https",protocol)) ? 443 : 0 )
CHttpXml::CHttpXml(void)
{
m_pXmlBuffer = NULL;
InitSate();
}
CHttpXml::~CHttpXml(void)
{
}
/*******************************************************************************
函数名称 : InitSate
函数描述 : 初始化状态
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
void CHttpXml::InitSate()
{
memset(m_szProtocol, 0 , MAX_URL_LEN+1);
memset(m_szHostPort, 0 , MAX_URL_LEN+1);
memset(m_szPath, 0 , MAX_URL_LEN+1);
memset(m_szReqHead, 0 , MAX_URL_LEN+1);
m_iXmlLength = 0;
m_iStartLength = 0;
m_iDateLength = 0;
if(NULL != m_pXmlBuffer)
{
delete []m_pXmlBuffer;
m_pXmlBuffer = NULL;
}
}
/*******************************************************************************
函数名称 : GetHostByName
函数描述 : 从网址获取ip地址
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
unsigned long CHttpXml::GetHostIpByName( const char *host )
{
unsigned long ip = 0;
struct hostent *hostinfo;
hostinfo = gethostbyname(host);
if (NULL == hostinfo)
{
return 0;
}
ip = *((unsigned long *)hostinfo->h_addr_list[0]);
return ip;
}
/*******************************************************************************
函数名称 : ParseUrl
函数描述 : 从url获取相关连接信息
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
BOOL CHttpXml::ParseUrl( const char* szUrl )
{
int port = 0;
char szHost[MAX_URL_LEN+1]={0};
char szPort[MAX_URL_LEN+1]={0};
if ( sscanf(szUrl,"%[^:]://%[^/]%1024s",m_szProtocol,m_szHostPort,m_szPath) != 3)
{
return FALSE;
}
sscanf(m_szHostPort,"%[^:]:%d",szHost,&port);
if (port == 0)
{
port = 80;
}
m_port = htons(GET_HOST_PORT(m_szProtocol,port));
m_iIP = GetHostIpByName(szHost);
return TRUE;
}
/*******************************************************************************
函数名称 : ReceiveDate
函数描述 : 接受所有数据
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
int CHttpXml::ReceiveDate(SOCKET& sd)
{
char buf[MAX_RX_LEN];
int iRecvlen = 0;
int ret = 1;
while (ret > 0)
{
//ret = recv(sd,buf,MAX_RX_LEN,0);
ret = AsynReceive(sd, &ReceiveBuffer[iRecvlen],SOKET_TIME_OUT);
if (ret > 0)
{
iRecvlen += ret;
continue;
}
else if (ret == 0)
{
return iRecvlen;
}
else// ret < 0//一次失败数据已经不完整于是就退出了
{
return -1;
}
}
return iRecvlen;
}
/*******************************************************************************
函数名称 : GetRecHeadLenth
函数描述 : 获取接收头长度
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
int CHttpXml::GetRecHeadLenth()
{
int iLength = strlen(ReceiveBuffer);
if(iLength == m_iDateLength)
{
int a = 0;
};
for (int i = 0; i < iLength -4; i++ )
{
if (ReceiveBuffer[i]=='\r' && ReceiveBuffer[i +1] == '\n' && ReceiveBuffer[i+2] == '\r' && ReceiveBuffer[i+3]=='\n')
{
return i+4;
}
}
return 0;
}
/*******************************************************************************
函数名称 : XmldataFromBuffer
函数描述 : 从接收数据中获取xml数据
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
BOOL CHttpXml::XmldataFromBuffer( void )
{
if(m_iDateLength <= 0 )
{
return FALSE;
}
m_iXmlLength = m_iDateLength - m_iStartLength;
if (m_iXmlLength <= 0)
{
return FALSE;
}
if (NULL != m_pXmlBuffer)
{
delete []m_pXmlBuffer;
m_pXmlBuffer = NULL;
}
m_pXmlBuffer = new char[m_iXmlLength + 1];
memcpy(m_pXmlBuffer ,&ReceiveBuffer[m_iStartLength], m_iXmlLength );
}
/*******************************************************************************
函数名称 : ReceiveXmlDate
函数描述 : 获取xml数据
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
BOOL CHttpXml::ReceiveXmlDate( const char* szUrl )
{
int ret = 0;
char szSent[MAX_RX_LEN + 1] = {0};
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2,2), &wsadata))
{
return FALSE;
}
struct sockaddr_in raddr;
SOCKET sd = socket(AF_INET,SOCK_STREAM,0);
raddr.sin_family = AF_INET;
ParseUrl(szUrl);
raddr.sin_addr.s_addr = m_iIP;
raddr.sin_port = m_port;
//ret = connect(sd,(struct sockaddr *)&raddr, sizeof(raddr));
ret = AsynConnect(sd,(struct sockaddr *)&raddr, sizeof(raddr), SOKET_TIME_OUT);
if(0 != ret)
{
return FALSE;
}
sprintf(szSent, "GET %s HTTP/1.1 \r\nHost: %s\r\n\r\n", m_szPath, m_szHostPort);
//ret = send(sd,szSent,strlen(szSent),0);
ret = AsynSend(sd,szSent,strlen(szSent),0, SOKET_TIME_OUT);
m_iDateLength = ReceiveDate(sd);
if (m_iDateLength <= 0)
{
return FALSE;
}
m_iStartLength = GetRecHeadLenth();
XmldataFromBuffer();
closesocket(sd);
WSACleanup();
return TRUE;
}
/*******************************************************************************
函数名称 : SaveXml
函数描述 : 存储xml数据
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
void CHttpXml::SaveXml( const char* szPath )
{
if(NULL == m_pXmlBuffer || m_iXmlLength <= 0)
{
return;
}
FILE * fp;
fp = fopen(szPath, "w");
fwrite(m_pXmlBuffer,m_iXmlLength, 1, fp );
fclose(fp);
}
/*******************************************************************************
函数名称 : GetXmlLength
函数描述 : 获取xml数据长度
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
int CHttpXml::GetXmlLength()
{
return m_iXmlLength;
}
/*******************************************************************************
函数名称 : GetXmlDate
函数描述 : 获取xml数据
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
BOOL CHttpXml::GetXmlDate( char* szBuffer )
{
if (m_iXmlLength <= 0 || NULL == m_pXmlBuffer)
{
return FALSE;
}
memcpy(szBuffer, m_pXmlBuffer, m_iXmlLength);
return TRUE;
}
/*******************************************************************************
函数名称 : SynConnect
函数描述 : 异步链接
输入参数 : N/A
输出参数 : N/A
返回值 : void
备注 : N/A
*******************************************************************************/
int CHttpXml::AsynConnect( IN SOCKET& sd, IN const struct sockaddr FAR *name, IN int namelen, IN int iTimeOut )
{
fd_set wfd; // 描述符集 这个将用来测�