first commit
This commit is contained in:
commit
f55752a979
335
CWeatherDataSpider.cpp
Normal file
335
CWeatherDataSpider.cpp
Normal file
|
@ -0,0 +1,335 @@
|
|||
|
||||
#include "CWeatherDataSpider.h"
|
||||
#include"AuxFun.h"
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
//#include<WinSock2.h>
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
#define RECV_BUFF_LENGTH 1024*10
|
||||
|
||||
#define WEATHER_REALTIME 0
|
||||
#define WEATHER_FORECAST 1
|
||||
CWeatherDataSpider::CWeatherDataSpider()
|
||||
{
|
||||
m_strAreaCode = "天津";
|
||||
}
|
||||
|
||||
|
||||
CWeatherDataSpider::~CWeatherDataSpider()
|
||||
{
|
||||
}
|
||||
|
||||
bool CWeatherDataSpider::GetWeatherDataXml()
|
||||
{
|
||||
//------------------创建描述符----------------------
|
||||
WSADATA wsadata;
|
||||
int ierror = -1;
|
||||
if (ierror = WSAStartup(MAKEWORD(2,2), &wsadata))
|
||||
{
|
||||
wchar_t tchTmp[100];
|
||||
swprintf(tchTmp,100, L"WSAStartup failure: %d\n", ierror);
|
||||
ErrHandle(tchTmp);
|
||||
return false;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (INVALID_SOCKET == m_socket)
|
||||
{
|
||||
ErrHandle(L"Create socket failed");
|
||||
WSACleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//unsigned long iMode = 1;
|
||||
//int retMode = ioctlsocket(m_socket, FIONBIO, (unsigned long *)&iMode);
|
||||
//if (retMode == SOCKET_ERROR)
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
//if(connect(sock, (SOCKADDR*)&sa, sizeof(sa)))
|
||||
|
||||
//连接主机
|
||||
if (!ConnectHost()) { goto bad; }
|
||||
|
||||
//发送请求
|
||||
if (!SendReq()) { goto bad; }
|
||||
//接收回应
|
||||
if (!HandleAck()) { goto bad; }
|
||||
else{ CloseConnect(); return true; }
|
||||
|
||||
bad:
|
||||
CloseConnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
void CWeatherDataSpider::CloseConnect()
|
||||
{
|
||||
if (m_socket)
|
||||
{
|
||||
closesocket(m_socket);
|
||||
}
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
void CWeatherDataSpider::ErrHandle(const std::wstring msg, int code)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CWeatherDataSpider::CheckIfRecSucceed(char * buf, int nTotalRecv, int nFlag)
|
||||
{
|
||||
int PosStart = -1;
|
||||
int PosEnd = -1;
|
||||
if (buf == NULL || nTotalRecv <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//解析回复是否是200
|
||||
//截取xml
|
||||
//
|
||||
std::string strHeadFind =buf;
|
||||
int n =strHeadFind.find("\r\n");
|
||||
if (-1 != (n = strHeadFind.rfind("200", n))) { return true; }
|
||||
|
||||
PosStart = strHeadFind.find("content-length: ");//该标签 加空格16个字符
|
||||
PosStart =PosStart + 16;
|
||||
PosEnd = strHeadFind.find("\r\n", PosStart);
|
||||
std::string strLen =strHeadFind.substr(PosStart, PosEnd-PosStart);
|
||||
|
||||
int nlen = atoi(strLen.c_str());
|
||||
|
||||
PosStart = strHeadFind.find("\r\n\r\n")+4;
|
||||
|
||||
char* Output = NULL;//= new char[10000];
|
||||
int iTotalRead = 0;
|
||||
inflate_read((char*)buf + PosStart, nlen, &Output, 1, iTotalRead);
|
||||
|
||||
|
||||
|
||||
// add by lei.zhao 2015-11-03, Bug[12533]
|
||||
//bool bNewPacket = false;
|
||||
//if (nFlag == WEATHER_FORECAST)
|
||||
//{
|
||||
// char bufTemp[RECV_BUFF_LENGTH] = { 0 };
|
||||
// memcpy_s(bufTemp, RECV_BUFF_LENGTH, buf, nTotalRecv);
|
||||
// bufTemp[nTotalRecv] = 0;
|
||||
//
|
||||
// CString strTemp;
|
||||
// strTemp = bufTemp;
|
||||
// strTemp = strTemp.MakeLower();
|
||||
// int nFindPos = strTemp.Find(L"content-length: ");
|
||||
|
||||
// if (nFindPos != -1)
|
||||
// {
|
||||
// int nLengthStart = nFindPos + 16;
|
||||
// int nLengthEnd = strTemp.Find(L"\r\n", nLengthStart);
|
||||
// if (nLengthEnd == -1)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// int nLength = _tstoi(strTemp.Mid(nLengthStart, nLengthEnd - nLengthStart));
|
||||
|
||||
// int nHearderLength = strTemp.Find(L"\r\n\r\n") + 4;
|
||||
// if (nHearderLength == -1)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// if (nHearderLength + nLength > nTotalRec)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// memset(m_pbyXmlBuf, 0, 10000);
|
||||
// char* Output = NULL;//= new char[10000];
|
||||
// int iTotalRead = 0;
|
||||
// inflate_read((char*)buf + nHearderLength, nLength, &Output, 1, iTotalRead);
|
||||
// memcpy_s(m_pbyXmlBuf, 10000, Output, iTotalRead);
|
||||
// delete[]Output;
|
||||
// bNewPacket = true;
|
||||
// }
|
||||
//}
|
||||
//if (!bNewPacket)
|
||||
//{
|
||||
// int nIndex = -1;
|
||||
// for (int i = 0; i< nTotalRec; i++)
|
||||
// {
|
||||
// if (buf[i] == '\r'
|
||||
// && buf[i + 1] == '\n'
|
||||
// && buf[i + 2] == '\r'
|
||||
// && buf[i + 3] == '\n'
|
||||
// )
|
||||
// {
|
||||
// nIndex = i + 4;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (nIndex <0)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// memset(m_pbyXmlBuf, 0, 10000);
|
||||
// if (nFlag == WEATHER_REALTIME)
|
||||
// {
|
||||
// memcpy_s(m_pbyXmlBuf, 10000, buf + nIndex, nTotalRec - nIndex);
|
||||
// }
|
||||
// else if (nFlag == WEATHER_FORECAST)
|
||||
// {
|
||||
// int nIndexR = nIndex;
|
||||
// bool bFindCount = false;
|
||||
// do
|
||||
// {
|
||||
// if (buf[nIndexR] == '\r' && buf[nIndexR + 1] == '\n')
|
||||
// {
|
||||
// bFindCount = true;
|
||||
// break;
|
||||
// }
|
||||
// ++nIndexR;
|
||||
// } while (nIndexR<nTotalRec);
|
||||
|
||||
// if (!bFindCount)
|
||||
// return false;
|
||||
|
||||
|
||||
// char chTmp[10] = { 0 };
|
||||
// memcpy_s(chTmp, sizeof chTmp, buf + nIndex, nIndexR - nIndex);
|
||||
// int nTmp = strtol(chTmp, NULL, 16);
|
||||
|
||||
// if (!(nTmp + nIndexR + 9 == nTotalRec))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// // FILE* file = fopen("D:\\Forecast_html.gz", "w");
|
||||
// // if (file == NULL)
|
||||
// // {
|
||||
// // return false;
|
||||
// // }
|
||||
|
||||
|
||||
// char* Output = NULL;//= new char[10000];
|
||||
// int iTotalRead = 0;
|
||||
// inflate_read((char*)buf + nIndexR + 2, nTmp, &Output, 1, iTotalRead);
|
||||
// memcpy_s(m_pbyXmlBuf, 10000, Output, iTotalRead);
|
||||
// delete[]Output;
|
||||
// }
|
||||
//}
|
||||
|
||||
//TiXmlDocument xmlDoc;
|
||||
//xmlDoc.Parse(m_pbyXmlBuf);
|
||||
|
||||
//if (xmlDoc.Error())
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//xmlDoc.SaveFile("D:\\demotest.xml");//for debug only
|
||||
//if (nFlag == WEATHER_REALTIME)
|
||||
//{
|
||||
// m_xmlDocRealTime = xmlDoc;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// m_xmlDocForecast = xmlDoc;
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWeatherDataSpider::SendReq()
|
||||
{
|
||||
//将 http://wthrcdn.etouch.cn/WeatherApi?city=天津 中文utf编码
|
||||
//转换为 http://wthrcdn.etouch.cn/WeatherApi?city=%E5%A4%A9%E6%B4%A5
|
||||
std::string SendTmp = MBCStoUTF8(m_strAreaCode.c_str());
|
||||
std::string SendTmp2 = UrlEncode(SendTmp);
|
||||
std::string strSnd = "GET /WeatherApi?city=" + SendTmp2;
|
||||
strSnd += " HTTP/1.1\r\n";
|
||||
strSnd += "HOST:wthrcdn.etouch.cn\r\n";
|
||||
strSnd += "Connection:close\r\n\r\n";
|
||||
strSnd += "User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:32.0) Gecko/20100101 Firefox/32.0\r\n\r\n";
|
||||
|
||||
if (SOCKET_ERROR == send(m_socket, strSnd.c_str(), strSnd.length(), 0))
|
||||
{
|
||||
int ret = WSAGetLastError();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//突然懒了,一次接收算了,整这么多幺蛾子木用
|
||||
bool CWeatherDataSpider::HandleAck()
|
||||
{
|
||||
char* pRecvBuff = new char[RECV_BUFF_LENGTH];//10kBbuff
|
||||
memset(pRecvBuff, 0, RECV_BUFF_LENGTH);
|
||||
|
||||
bool bIfRecSucceed = false;
|
||||
int nTotalNum = 0;
|
||||
int nRet = SOCKET_ERROR;
|
||||
do
|
||||
{
|
||||
nRet = recv(m_socket, (char*)pRecvBuff + nTotalNum, RECV_BUFF_LENGTH, 0);
|
||||
|
||||
if (nRet == SOCKET_ERROR)
|
||||
{
|
||||
int r = WSAGetLastError();
|
||||
break;
|
||||
}
|
||||
else if (nRet == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
nTotalNum += nRet;
|
||||
if (CheckIfRecSucceed(pRecvBuff, nTotalNum, 0))
|
||||
{
|
||||
printf("%s", pRecvBuff);
|
||||
bIfRecSucceed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
|
||||
delete[] pRecvBuff;
|
||||
if (!bIfRecSucceed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CWeatherDataSpider::ConnectHost()
|
||||
{
|
||||
sockaddr_in sa;
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(80);
|
||||
|
||||
struct hostent *lphost;
|
||||
lphost = gethostbyname("wthrcdn.etouch.cn");
|
||||
|
||||
if (lphost != NULL)
|
||||
{
|
||||
sa.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseConnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
//成功返回0
|
||||
int nRet = connect(m_socket, (SOCKADDR*)&sa, sizeof(sa));
|
||||
|
||||
if (!nRet)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int wsaErr = WSAGetLastError();
|
||||
std::wstring strErr = L"connect err";
|
||||
ErrHandle(strErr, wsaErr);
|
||||
return false;
|
||||
|
||||
}
|
Reference in New Issue
Block a user