• 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
    ";
    	cstrSendData += "Host:     
    ";
    	cstrSendData += "Connection: keep-alive
    ";
    	cstrSendData += "Accept: image/webp,image/*,*/*;q=0.8
    ";
    	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
    ";
    	cstrSendData += "Referer:
    ";
    	cstrSendData += "Accept-Encoding: gzip, deflate, sdch
    ";
    	cstrSendData += "Accept-Language: zh-CN,zh;q=0.8
    ";
    	cstrSendData += "Cookie: JSESSIONID=" + sessionid + "
    ";
    	cstrSendData += "
    ";
    
    
    	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  两个
      一个 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;
    }  
    

      转载请标明出处。

  • 相关阅读:
    JWT与Session的比较
    Java面试-TCP连接及其优化
    Java面试-动态规划与组合数
    探索Redis设计与实现12:浅析Redis主从复制
    探索Redis设计与实现11:使用快照和AOF将Redis数据持久化到硬盘中
    探索Redis设计与实现10:Redis的事件驱动模型与命令执行过程
    探索Redis设计与实现9:数据库redisDb与键过期删除策略
    探索Redis设计与实现8:连接底层与表面的数据结构robj
    探索Redis设计与实现6:Redis内部数据结构详解——skiplist
    探索Redis设计与实现7:Redis内部数据结构详解——intset
  • 原文地址:https://www.cnblogs.com/tshua/p/5313132.html
Copyright © 2020-2023  润新知