This repository has been archived on 2021-11-25. You can view files and clone it, but cannot push or open issues/pull-requests.
JZFamily-HelloWorld/CWeatherDataSpider.cpp

226 lines
4.5 KiB
C++

#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);
//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;
}