c/c++ socket发送http请求访问网站

Posted 紫色年华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c/c++ socket发送http请求访问网站相关的知识,希望对你有一定的参考价值。

这几天课比较少,校园网上网要认证才能上网,每次必须输入学号密码,为了方便,写了一个自动登录以及如果在线,登录自服务系统强制下线的小工具。

强制下线思路:获取sessionID----------》获取验证码图片------------》AspriseOCRLib识别验证码---------------》MD5加密、url Encode----------------》登录自服务系统----------------》强制下线---------------------》退出登录。

 

需要注意的问题:

1、获取验证码时,发送完请求应该Sleep 1秒,等待接收完毕,再调用recv读缓冲区,否则可能图片为接受完。

2、登录请求后需要延时,等待服务器把登录状态set进session中,才可以进行操作。

3、每次发送请求需要使用不同的socket连接。

 

 

下面贴一部分代码:(代码有很多疏漏之处,欢迎指正,共同进步)

 

转载请标明出处。

 

1、获取连接

 1 BOOL CforceOutLineDlg::ConnectToServer(const CString strServerUrl,SOCKET& socketClient, const unsigned short nPort)
 2 {   
 3     BOOL bRet = FALSE;  
 4     WSADATA wsaData;
 5     WORD wVersion = MAKEWORD(2,2);
 6 
 7     do   
 8     {  
 9         if(0 != WSAStartup(wVersion, &wsaData))  
10         {  
11             break;  
12         }  
13 
14         if(LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )  
15         {  
16             WSACleanup();  
17             break;  
18         }  
19 
20         LPHOSTENT lpHostTent;  
21         lpHostTent = gethostbyname(strServerUrl);///根据url获取ip
22         if (NULL == lpHostTent)  
23         {
24             break;  
25         }
26 
27         
28         if (socketClient == INVALID_SOCKET)  
29         {  
30             WSACleanup();  
31             break;  
32         }  
33 
34         SOCKADDR_IN socketServer;//服务器
35         socketServer.sin_family = AF_INET;  
36         socketServer.sin_port = htons(nPort);  
37         socketServer.sin_addr = *((LPIN_ADDR)*lpHostTent->h_addr_list);  
38 
39 
40         socketClient = socket(AF_INET, SOCK_STREAM, 0);
41 
42         if (SOCKET_ERROR == connect(socketClient, (LPSOCKADDR)&socketServer, sizeof(SOCKADDR_IN)))  
43         {
44             int nErrorCode = WSAGetLastError();  
45             closesocket(socketClient);  
46             break;
47         }  
48 
49         bRet = TRUE;  
50     } while (FALSE);
51 
52     return bRet;
53 }  

2、接收验证码

BOOL CforceOutLineDlg::GetValidateCode(/*SOCKET s,*/CString sessionid)
{
	SOCKET client;
	ConnectToServer("IP",client);//初始化连接

	CString cstrSendData;

	cstrSendData = "GET /RandomCodeAction.action?randomNum=0.1 HTTP/1.1\r\n";
	cstrSendData += "Host:     \r\n";
	cstrSendData += "Connection: keep-alive\r\n";
	cstrSendData += "Accept: image/webp,image/*,*/*;q=0.8\r\n";
	cstrSendData += "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/49.0.2623.87 Safari/537.36\r\n";
	cstrSendData += "Referer:\r\n";
	cstrSendData += "Accept-Encoding: gzip, deflate, sdch\r\n";
	cstrSendData += "Accept-Language: zh-CN,zh;q=0.8\r\n";
	cstrSendData += "Cookie: JSESSIONID=" + sessionid + "\r\n";
	cstrSendData += "\r\n";


	if (-1 == send(client, cstrSendData.GetBuffer(), cstrSendData.GetLength(), 0))  
	{  
		return FALSE;
	}

	char buff[4096]={0};

	Sleep(1000);//延时1秒,等待图片流接收完毕

	recv(client, buff, sizeof(buff),0);

	CString temp = buff;

	int nFirst = temp.Find("close",0);

	if(nFirst == -1)
		return FALSE;

	nFirst += 9;//加上close  两个\r\n  一个 0 的长度

	int picLength = GetPicLength(buff+nFirst);

	ofstream out("aa.png",ios::out|ios::binary);

	out.write(buff+nFirst,picLength);

	out.flush();

	out.close();

	closesocket(client);

	return TRUE;
}



int CforceOutLineDlg::GetPicLength(char* pic)//查找到连续5个 0x00 的位置
{
	int count = 0,i;
	for(i = 0;;i++)
	{
		if(pic[i]==0)
		{
			count++;
			if(count==5)
			{
				break;
			}
		}
		else
		{
			count = 0;
		}
	}
	return i-4;
}

3、URlEncode

CString CforceOutLineDlg::UrlEncode(const CString& szToEncode)
{  
	std::string src = szToEncode;  
	char hex[] = "0123456789ABCDEF";  
	CString dst;  


	for (size_t i = 0; i < src.size(); ++i)  
	{  
		unsigned char cc = src[i];
		if(cc == ‘\\‘)
			continue;

		if ( cc >= ‘A‘ && cc <= ‘Z‘   
			|| cc >=‘a‘ && cc <= ‘z‘  
			|| cc >=‘0‘ && cc <= ‘9‘  
			|| cc == ‘.‘  
			|| cc == ‘_‘  
			|| cc == ‘-‘  
			|| cc == ‘*‘
			)  
		{  
			if (cc == ‘ ‘)  
			{  
				dst += "+";  
			}  
			else  
				dst += cc;  
		}  
		else  
		{  
			unsigned char c = static_cast<unsigned char>(src[i]);  
			dst += ‘%‘;  
			dst += hex[c / 16];  
			dst += hex[c % 16];  
		}  
	}  

	return dst;
}  

  转载请标明出处。

以上是关于c/c++ socket发送http请求访问网站的主要内容,如果未能解决你的问题,请参考以下文章

值得学习的C/C++开源框架(转)

浏览器的一个请求从发送到返回经历了什么(转)

Python模拟浏览器实现网页访问

(转) 用户访问网站基本流程及原理(史上最全,没有之一)

Socket请求和Http请求的各自特点区别及适用场景 (转)

socket 发送http请求