一个简单的天气服务程序

来源:互联网 发布:moedaze 优化 编辑:程序博客网 时间:2024/05/16 10:44

一个简单的提供天气预报信息的服务程序

这是本人第一次写的一个服务器程序,也是第一次接触服务器程序开发。对于天气信息,事实上可以直接从中国天气网上取得天气信息,这里之所以需要开发自己的天气服务程序,是因为原有的终端已固定,并且终端的处理能力有限。

程序分为三个模块:天气信息提供模块、数据处理模块、消息收发模块。


天气信息提供模块:从中国天气网m.weather.com.cn上取得对应城市的天气信息,经过预定义好的格式处理后保存在内存中,提供统一的接口给调用者获取。我们知道,肯定会出现大量的对同一城市的天气信息获取,因此我们可以一次过把所有城市的天气信息取得,处理后保存在内存中,需要获取天气时将直接从内存中读取,而不是又到中国天气网中获取。对于这样的处理方法,我们还需要定时更新内存中的天气信息,令到天气信息保持最新。更新的方式采用更新天气信息内存指针的方式,因为由于网络的原因,要更新完所有城市天气信息需要一段时间。当更新完毕只要更换天气信息的内存指针即可。至于更新频率,我们提供一个借口,让使用者自己设定更新频率。

数据处理模块:负责将接收到的信息解析,调用各个处理模块产生结果,把结果返回给调用者。

信息收发模块:利用win32的完成端口模式,负责对消息的收发和与客户建立连接。

 

下面是部分源代码说明,完整的源代码可以点击这里下载

天气信息提供模块

#ifndef      _WEATHER_CLASS_H

#define     _WEATHER_CLASS_H

 

#include <vector>

#include <list>

#include "TCPClient.h"

 

using namespace std;

 

//从文件中读取的城市编号及自定义索引

class CityInfoClass

{

public:

         CityInfoClass(constint index = 0, const int cityId = 0) : m_index(index), m_cityId(cityId){}

         CityInfoClass(constCityInfoClass &obj) : m_index(obj.m_index), m_cityId(obj.m_cityId){}

 

public:

         intm_index;

         intm_cityId;

 

public:

         booloperator==(const CityInfoClass &city)

         {

                   returnm_index == city.m_index;

         }

         booloperator>=(const CityInfoClass &city)

         {

                   returnm_index >= city.m_index;

         }

         booloperator<=(const CityInfoClass &city)

         {

                   returnm_index <= city.m_index;

         }

 

         booloperator>(const CityInfoClass &city)

         {

                   returnm_index > city.m_index;

         }

 

         booloperator<(const CityInfoClass &city)

         {

                   returnm_index < city.m_index;

         }

};

 

#define CMP_WCHAR(str1, str2)    (wcscmp((str1), (str2)) == 0)

#define NCMP_WCHAR(str1, str2) (wcsncmp((str1), (str2), wcslen((str2))) == 0)

#define CMP_CHAR(str1, str2)        (strcmp((str1), (str2)) == 0)

#define NCMP_CHAR(str1, str2)     (strncmp((str1), (str2), strlen(str2)) ==0)

#define MIN(a, b)                                ((a) > (b) ? (b) : (a))

 

/***城市天气信息**/

struct WeatherStruct

{

         int  m_cityid;                    //城市//ID

         int  m_index;                    //索引

         charm_date[16];              //日期

         charm_humidity[16];      //湿度

         charm_win[256];              //风速

         charm_condname[256]; //天气状况(文本信息)

         unsignedchar m_temp1[2];    //当天气温

         unsignedchar m_temp2[2];    //第二天气温

         unsignedchar m_temp3[2];    //第三天气温

         unsignedchar m_temp4[2];    //第四天气温

         unsignedchar m_temp5[2];    //第五天气温

         unsignedchar m_temp6[2];    //第六天气温

         unsignedchar m_condition1;  //当天天气状况

         unsignedchar m_condition2;  //第二天天气状况

         unsignedchar m_condition3;  //第三天天气状况

         unsignedchar m_condition4;  //第四天天气状况

         unsignedchar m_condition5;  //第五天天气状况

         unsignedchar m_condition6;  //第六天天气状况

};

 

 

class WeatherInformationClass

{

public:

         staticconst int NONE_FORMAT_FLAG = 0;                        //不做处理

         staticconst int DATE_FORMAT_FLAG = 1;                         //处理日期

         staticconst int TEM1_FORMAT_FLAG = 2;                        //当天气温

         staticconst int TEM2_FORMAT_FLAG = 3;                        //第二天气温

         staticconst int TEM3_FORMAT_FLAG = 4;                        //第三天气温

         staticconst int TEM4_FORMAT_FLAG = 5;                        //第四天气温

         staticconst int TEM5_FORMAT_FLAG = 6;                        //第五天气温

         staticconst int TEM6_FORMAT_FLAG = 7;                        //第六天气温

         staticconst int CON1_FORMAT_FLAG = 8;                        //当天天气状况weather        1

         staticconst int CON2_FORMAT_FLAG = 9;                        //第二天天气状况weather2

         staticconst int CON3_FORMAT_FLAG = 10;                      //第三天天气状况weather3

         staticconst int CON4_FORMAT_FLAG = 11;                      //第四天天气状况weather4

         staticconst int CON5_FORMAT_FLAG = 12;                      //第五天天气状况weather5

         staticconst int CON6_FORMAT_FLAG = 13;                      //第六天天气状况weather6

         staticconst int WIN1_FORMAT_FLAG = 14;                      //当天风速

        

         //根据天气状况的数值获得文本英文描述

         staticstring GetConditionEnglishStr(int conditon);

 

public:

         WeatherInformationClass();

         ~WeatherInformationClass();

 

         //获取固定格式的天气信息

         stringGetCityWeatherSendFormat(int cityindex, int language);

         //由客户选择的定期更新

         boolUpdateByUser();

 

private:

         //获取城市列表ID

         voidInitialCityID();

         //更新天气信息

         boolUpdateWeather(vector<WeatherStruct> *pweather);

 

         //格式化天气信息

         voidFormatWeather(char *info, int info_len, WeatherStruct &weather);

         //将格式为"xxxx年x月x日"格式的日期处理为"xxxx-xx-xx"格式

         voidFormatDate(const string &str, char *date);

         //将格式为"27℃~22℃"的温度格式处理为temp[0]=最高气温,temp[1]=最低气温

         voidFormatTemp(const string &str, unsigned char temp[2]);

         //将天气状态信息转化为整数标志

         voidFormatWeather(const string &str, unsigned char &condition);

         //以对半查找法获取城市对应的在容器中的位置

         intBinarySearchCity(int cityindex);

 

private:

         CRITICAL_SECTION                   m_context;                         //更新数据时的临界保护

         bool                                                m_updating;                       //标志更新状态

         TCPClient                                               m_tcp;                                 //TCP的客户端对象      

         list<CityInfoClass>                     m_city;                                 //城市ID

         vector<WeatherStruct>            *m_pweather;                   //天气信息

};

#endif                //_WEATHER_CLASS_H

 

信息收发模块

#ifndef      _WEATHER_SERVER_H_

#define _WEATHER_SERVER_H_

 

#include <winsock2.h>

#include <mswsock.h>

 

#define SEND 0                                              //发送操作

#define RECV 1                                              //接收操作

#define QUIT 2                                               //退出线程

 

#define DATA_LENGTH                                4096                            //缓冲区大小

 

//单句柄数据定义

typedef struct _PER_HANDLE_DATA

{

         SOCKETsocket;                                             //相关的套接字

}PER_HANDLE_DATA, *LPPER_HANDLE_DATA;

 

//单IO操作数据

typedef struct{

         OVERLAPPED            overlapped;

         WSABUF                     buffer;                                                              //一个数据缓冲区,用于WSASend/WSARecv中的第二个参数

         char                    dataBuffer[DATA_LENGTH];             //实际的数据缓冲区

         int                                dataLength;                     //实际的数据缓冲区长度

         int                                operatorType;                                       //操作类型,可以为SEND/RECV两种

}PER_IO_DATA, *LPPER_IO_DATA;

 

class WeatherServerClass

{

public:

         staticconst int UPDATE_WEATHER_DURATION = 3600 * 1000;//更新天气信息间隔

         staticconst int LISTEN_NUMER = 32;                                          //监听队列数量     

 

private:

         staticDWORD WINAPI ServerAcceptThread(LPVOID lpParam);    //接受连接线程

         staticDWORD WINAPI ServerWorkerThread(LPVOID lpParam);   //工作者线程

         staticDWORD WINAPI CheckConnectThread(LPVOID lpParam);  //定时检测连接状态函数

         staticDWORD WINAPI UpdateWeatherThread(LPVOID lpParam);//定时更新天气信息函数

         staticbool ProcessMessage(char *buff, char *dataBuffer, int &dataLength);       //处理消息函数

 

public:

         WeatherServerClass();

 

         boolWeatherServerStart(short port);                        //启动服务

         voidWeatherServerStop();       //关闭服务

};

#endif

原创粉丝点击