这几天课比较少,校园网上网要认证才能上网,每次必须输入学号密码,为了方便,写了一个自动登录以及如果在线,登录自服务系统强制下线的小工具。
强制下线思路:获取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; }
转载请标明出处。