www.pudn.com > duanxinfangwei.rar > HttpServe.cpp


// HttpServe.cpp: implementation of the CHttpServe class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "smspreventforgery.h" 
#include "HttpServe.h" 
#include "BLOCKSOCK.H" 
#include "CodeQuery.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
/* HTTP服务器 */ 
 
/* 宏定义 */ 
#define SERVERMAXBUF 5000 
#define MAXLINELENGTH 256 
 
/* 常量定义 */ 
const CString BEFORESTRING				= _T("/"); 
const CString REQUESTURL_QUERYCODE		= _T("/QUERY");		//查询防伪链接 
 
/* 全局变量 */ 
volatile int g_nConnection=0;								//连接的个数 
volatile BOOL g_bListening=FALSE;							//侦听套接字状态 
volatile UINT g_nPortServer=81;								//服务端口 
CString g_strIPServer;										//服务器地址 
CMyBlockSocket g_sListen;									//侦听套接字 
 
/********************************************************************** 
 * 函数名	:	MakeReturnToM2pString 
 * 功能		:	生成M2P要求格式信息 
 * 	 
 *********************************************************************/ 
CString MakeReturnToM2pString(CString info) 
{ 
	CString result; 
 
	result = "0"; 
	result += info; 
	result += ""; 
 
	return result; 
} 
 
/********************************************************************** 
 * 函数名:	ParseUrlInfo 
 * 功  能:	解析请求信息 
 * 参  数:	CString							请求信息 
 *		 :  CString&						手机号 
 *		 :  CString&						短信内容 
 *		 :  CString&						用户ID 
 *********************************************************************/ 
bool ParseUrlInfo(CString requestString, CString& mobile, CString& sms, CString& userId) 
{ 
	/* 常量定义 */ 
	const CString SPILTFLAG		= "&";			//参数联接标志 
	const CString MOBILEFLAG	= "mobile=";	//手机号开始标志 
	const CString SMSFLAG		= "sms=";		//短信内容开始标志 
	const CString CODE			= "code=";		//指令代码 
	const CString USERID		= "userid=";	//M2P用户ID 
 
	/* 变量定义 */ 
	int startpos;								//开始位置 
	int endpos;									//结束位置 
 
	/* 处理参数 */ 
	requestString.TrimLeft(); 
	requestString.TrimRight(); 
	mobile.Empty(); 
	sms.Empty(); 
	userId.Empty(); 
 
	/* 取手机号 */ 
	startpos = requestString.Find(MOBILEFLAG); 
	if(startpos < 0) 
	{ 
		sms.Empty(); 
		return false; 
	} 
	endpos = requestString.Find(SPILTFLAG, startpos + MOBILEFLAG.GetLength()); 
	if(endpos < 0) 
	{ 
		endpos = requestString.GetLength(); 
	} 
	mobile = requestString.Mid(startpos + MOBILEFLAG.GetLength(), endpos - startpos - MOBILEFLAG.GetLength()); 
 
	/* 取短信内容 */ 
	startpos = requestString.Find(SMSFLAG); 
	if(startpos < 0) 
	{ 
		return true; 
	} 
	endpos = requestString.Find(SPILTFLAG, startpos + SMSFLAG.GetLength()); 
	if(endpos < 0) 
	{ 
		endpos = requestString.GetLength(); 
	} 
	sms = requestString.Mid(startpos + SMSFLAG.GetLength(), endpos - startpos - SMSFLAG.GetLength()); 
 
	/* 取用户ID */ 
	startpos = requestString.Find(USERID); 
	if(startpos < 0) 
	{ 
		return true; 
	} 
	endpos = requestString.Find(SPILTFLAG, startpos + USERID.GetLength()); 
	if(endpos < 0) 
	{ 
		endpos = requestString.GetLength(); 
	} 
	userId = requestString.Mid(startpos + USERID.GetLength(), endpos - startpos - USERID.GetLength()); 
 
	return true; 
} 
 
 
//解析请求 
BOOL Parse(char* pStr, char** ppToken1, char** ppToken2) 
{ 
	*ppToken1=pStr; 
	char* pch=strchr(pStr, ' '); 
	if(pch)  
	{ 
		*pch='\0'; 
		pch++; 
		*ppToken2=pch; 
		pch=strchr(pch, ' '); 
		if(pch) { 
			*pch='\0'; 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
//打开文件 
void LogRequest(LPVOID pParam, char* pch, CSocketAddress sa) 
{ 
	//pParam参数保存了CListBox对象的指针 
	CString strList; 
	CListBox* pList=(CListBox*)pParam; 
	CString strGmt=CTime::GetCurrentTime().FormatGmt("%m/%d/%y %H:%M:%S GMT"); 
	strList.Format("服务器连接 # %d ",g_nConnection); 
	pList->AddString(strList); 
	strList.Format("     IP地址:%s 端口:%d",sa.DottedDecimal(), sa.Port()); 
	pList->AddString(strList); 
	strList.Format("     时间:%s",strGmt); 
	pList->AddString(strList); 
	strList.Format("     请求:%s",pch); 
	pList->AddString(strList); 
} 
 
//记录错误信息 
void LogBlockingSocketException(LPVOID pParam, char* pch, CMyBlockSocketException* pe) 
{ 
	//pParam参数保存了CListBox对象的指针 
	CListBox* pList=(CListBox*)pParam; 
	CString strGmt = CTime::GetCurrentTime().FormatGmt("%m/%d/%y %H:%M:%S GMT"); 
	char text2[50]; 
	pe->GetErrorMessage(text2, 49); 
	CString strList; 
	pList->AddString(strList); 
	strList.Format("WINSOCK错误"); 
	pList->AddString(strList); 
	strList.Format("     %s",pch); 
	pList->AddString(strList); 
	strList.Format("     错误信息:%s",text2); 
	pList->AddString(strList); 
	strList.Format("     时间:%s",strGmt); 
	pList->AddString(strList); 
} 
 
UINT ServerThreadProc(LPVOID pParam) 
{ 
	CSocketAddress saClient; 
	CMyHttpBlockSocket sConnect; 
 
	//缓存区 
	char* buffer=new char[SERVERMAXBUF]; 
	char headers[500],  
		 request1[MAXLINELENGTH],   
		 request2[MAXLINELENGTH]; 
	//连接错误返回到浏览的信息 
	char hdrErr[]= 
		"对象没有找到\r\n"; 
	//连接正确时返回的信息 
	char hdrFmt[]= 
		"HTTP/1.0 200 OK\r\n" 
		"Server: MySocket Server\r\n" 
		"Date: %s\r\n" 
		"Content-Type: text/html\r\n" 
		"Accept-Ranges: bytes\r\n" 
		"Content-Length: %d\r\n"; 
	//正常时返回信息 
	CString normalInfo; 
	 
	CString strGmtNow= 
		CTime::GetCurrentTime().FormatGmt("%a, %d %b %Y %H:%M:%S GMT"); 
	int nBytesSent=0; 
	CFile* pFile=NULL; 
	char* pToken1; 
	char* pToken2; 
	CString requestString;		//请求地址及字符串 
 
	requestString.Empty(); 
 
	try  
	{ 
		//开始侦听连接请求 
		if(!g_sListen.Accept(sConnect, saClient))  
		{ 
			//在应用程序关闭时的处理 
			g_bListening=FALSE; 
			delete [] buffer; 
			return 0; 
		} 
		//连接数增加一个 
		g_nConnection++; 
		//开始另一个服务器线程 
		AfxBeginThread(ServerThreadProc, pParam, THREAD_PRIORITY_NORMAL); 
		//从客户端(浏览器)读取请求 
		sConnect.ReadHttpHeaderLine(request1, MAXLINELENGTH, 10); 
		//解析请求并作相应的处理 
		if(Parse(request1, &pToken1, &pToken2)) 
		{ 
			//浏览器GET方式 
			if(!stricmp(pToken1, "GET"))  
			{ 
				do  
				{	 
					//读取请求的剩余部分 
					sConnect.ReadHttpHeaderLine(request2, MAXLINELENGTH, 10); 
				} 
				while(strcmp(request2, "\r\n")); 
 
				requestString = pToken2; 
 
				if(requestString.Find(REQUESTURL_QUERYCODE) == 0) 
				{ 
					if(!requestString.CompareNoCase(REQUESTURL_QUERYCODE)) 
					{//无参数 
						normalInfo += "接口测试返回信息"; 
					} 
					else 
					{ 
						CString mobile; 
						CString sms; 
						CString uerId; 
						/* 取得链接信息 */ 
						requestString = requestString.Mid(REQUESTURL_QUERYCODE.GetLength() + 1); 
						if(ParseUrlInfo(requestString, mobile, sms, uerId)) 
						{ 
							CCodeQuery 	codeQuery; 
							normalInfo += codeQuery.QueryCode(mobile, sms); 
						} 
						else 
						{ 
							normalInfo += "解析参数出错!"; 
						}				 
					} 
					normalInfo = MakeReturnToM2pString(normalInfo); 
					/* 返回结果 */ 
					wsprintf(headers, hdrFmt, (const char*) strGmtNow, strlen(normalInfo)); 
					strcat(headers, "\r\n"); 
					sConnect.Write(headers, strlen(headers), 10); 
					sConnect.Write(normalInfo, strlen(normalInfo), 10); 
				} 
				else 
				{ 
					sConnect.Write(hdrErr, strlen(hdrErr), 10); 
				} 
			} 
			else if(!stricmp(pToken1, "POST")) 
			{ 
				//浏览器POST方式 
				do  
				{ 
					//读取请求的剩余部分 
					sConnect.ReadHttpHeaderLine(request2, MAXLINELENGTH, 10); 
				} 
				while(strcmp(request2, "\r\n")); 
				sConnect.ReadHttpHeaderLine(request2, MAXLINELENGTH, 10); 
//				LogRequest(pParam, request2, saClient); 
				//向浏览器发送“出错信息” 
				nBytesSent=sConnect.Write(hdrErr, strlen(hdrErr), 10); 
			} 
			else  
			{ 
				//其它的请求方式 
			} 
		} 
		else  
		{ 
			//错误的请求 
		} 
		//关闭套接字 
		sConnect.Close(); 
		//连接数减一个 
		g_nConnection--; 
	} 
	catch(CMyBlockSocketException* pe) 
	{ 
		//错误处理 
//		LogBlockingSocketException(pParam, "服务器:", pe); 
		pe->Delete(); 
	} 
	delete [] buffer; 
	if(pFile) delete pFile; 
	return 0; 
} 
 
void StartHttpServe() 
{ 
	CSocketAddress saServer; 
	if(g_strIPServer.IsEmpty())  
	{ 
		saServer = CSocketAddress(INADDR_ANY, (USHORT) g_nPortServer); 
	} 
	else  
	{ 
		saServer = CSocketAddress(g_strIPServer, (USHORT) g_nPortServer); 
	} 
	g_sListen.Create(); 
	//绑定地址 
	g_sListen.Bind(saServer); 
	//开始侦听 
	g_sListen.Listen(); 
	g_bListening = TRUE; 
	g_nConnection = 0; 
	AfxBeginThread(ServerThreadProc, NULL, THREAD_PRIORITY_NORMAL);	 
} 
 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CHttpServe::CHttpServe() 
{ 
 
} 
 
CHttpServe::~CHttpServe() 
{ 
 
}