⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 requestvalidator.cpp

📁 离线的RSS阅读器
💻 CPP
字号:
#include "StdAfx.h"
#include "RequestValidator.h"

const int BUFFER_SIZE = 80;

CRequestValidator::CRequestValidator(void)
{
}

CRequestValidator::~CRequestValidator(void)
{
}

// 验证是否为有效的主机字符
bool CRequestValidator::IsValidHostChar(char ch)
{
    return( isalpha(ch) || isdigit(ch)
        || ch=='-' || ch=='.' || ch==':' );
}

void CRequestValidator::ParseURL(const char* url, char* host, int lHost, char* path, int lPath, int* port)
{
	char* work = new char[strlen(url) + 1];
	strcpy(work, url);
    strupr(work);									// 全部转为大写

    char* ptr = strchr(work,':');					// 通过':'来查找协议名,如http://
	if (ptr != NULL)
	{
		ptr++;										// 如果有协议名,则跳到协议名后面的'/'处
	}
    if( (*ptr == '/') && (*(ptr+1) == '/') )		// 如果可能,跳过':'后的'//' 
        ptr+=2;

    char* ptr2 = ptr;										
    while( IsValidHostChar(*ptr2) && *ptr2 )		// 如果url中碰到任何一个无效主机名字符,则终止,仅取有效字符
        ptr2++;

    *ptr2 = '\0';									// 碰到'/'或其它无效主机名字符,结束主机名
	lstrcpyn(host, ptr, lHost);
    lstrcpyn(path,url + (ptr2-work), lPath);		// 将主机名以后的部分放入request中

	ptr = strchr(host,':');							// 查找端口号(如果有)
    if(ptr != NULL)
    {
        *port = atoi(ptr+1);
    }

    delete[] work;
}

DWORD CRequestValidator::GetHostAddress(LPCSTR host)
{
    struct hostent *phe;
    char *p;

    phe = gethostbyname( host );
            
    if(phe==NULL)
        return 0;
    
    p = *phe->h_addr_list;
    return *((DWORD*)p);
}

void CRequestValidator::SendString(SOCKET sock,const char* str)
{
    send(sock,str,strlen(str),0);
}

// 取得响应的状态码。只取'.'之前的状态码
int CRequestValidator::GetCodeNumber(const char* str)
{
	// HTTP/1.1 404 Not Found
	// HTTP/1.1 200 OK
	char work[BUFFER_SIZE];
	lstrcpyn(work, str, BUFFER_SIZE);

	char* p = work;
	while (*p == ' ' || *p == '\r' || *p == '\n')	// 去除开头处的空格或空行
		p++;
	
	// 寻找第一个空格以便确定返回码的起点
	char* p1 = (char*)strchr(p, ' ');
	while (*p1 == ' ')								// 去除返回码前所有的空格
		p1++;
	
	char* p2 = p1;
	while (*p2 != ' ' && *p2 != '.')				// 遍历到返回码后的空格,或者返回码的'.'分隔符
		p2++;
	*p2 = '\0';

	int code = atoi(p1);
	return code;
}

int CRequestValidator::GetResponseCode(const char* url)
{
	char host[256];
	char path[1024];
	int port = 80;
	ParseURL(url,host,sizeof(host), path, sizeof(path), &port);
	if (path[0] == '\0')							// 如果没有子路径,则默认为'/';
	{
		strcpy(path, "/");
	}

	WSADATA			wsaData;
    SOCKADDR_IN		sin;
    SOCKET			sock;

	int ret = WSAStartup(MAKEWORD(2,2), &wsaData);							
    if (ret != 0)
        return -1;
	
	sock = socket (AF_INET, SOCK_STREAM, 0);
	if (sock == INVALID_SOCKET)
	{
		return -1;
	}

	sin.sin_family = AF_INET;										
    sin.sin_port = htons( (unsigned short)port );
    sin.sin_addr.s_addr = GetHostAddress(host);

	ret = connect(sock,(sockaddr*)&sin, sizeof(SOCKADDR_IN));		// 连接到远程服务器
	if (ret == SOCKET_ERROR)
	{
        return -1;
	}

	// 向服务器发送http请求
	SendString(sock,"GET ");
	SendString(sock,path);
	SendString(sock," HTTP/1.0\r\n");
	SendString(sock,"Accept: text/xml\r\n");
	SendString(sock,"Host: ");
	SendString(sock,host);
	SendString(sock,"\r\n");										// 请求结尾有两个空行
	SendString(sock,"\r\n");			

	char buf[BUFFER_SIZE];
	// 仅接收服务器响应的状态码
	int length = recv(sock, buf, BUFFER_SIZE-1, 0);
	closesocket(sock);
	if (length == 0)
		return -1;
	buf[length] = '\0';
	return GetCodeNumber(buf);	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -