/***************code.h********************/ #ifndef _CODE_H_ #define _CODE_H_ #include <string> using namespace std; class CCode { public: string Encode(const string & str); string Decode(const string & str); }; #endif /*****************code.cpp*************************/ #include “code.h” string CCode::Encode(const string & str) { string ret=”"; char buf[20]; int i=0; while(i<str.length()) { if(str[i] & 0×80) { sprintf(buf,”%%%1X%1X”,(unsigned char)str[i],(unsigned char)str[i+1]); ++i; ret+=buf; } else ret+=str[i]; ++i; } return ret; } string CCode::Decode(const string & str) { string ret=”"; string cur,all=str; while(all.length()>0) { int pos=all.find(“%”); if(pos!=0) ret+=all.substr(0,pos); cur=all.substr(pos+1,2); all=all.substr(pos+3); char ch; sscanf(cur.c_str(),”%x”,&ch); ret+=(char)ch; } return ret; } /*************************http.h***************************/ #ifndef _HTTP_H_ #define _HTTP_H_ #include <winsock2.h> #include <iostream> #include <string> using namespace std; #pragma comment(lib,”ws2_32.lib”) #define BUFFER_SIZE 11400 class CHttp { public: CHttp(); virtual ~CHttp(); private: SOCKET m_SOCKET; WSADATA m_WSADATA; HOSTENT * m_HOSTENT; SOCKADDR_IN m_SOCKADDR_IN; char buf[BUFFER_SIZE]; int len; private: bool CreateSocket(); void ReleaseSocket(); public: bool Connect(const string & httpAddr,const int port=80); int SendData(const char * str); string RecvData(); }; #endif /************************http.cpp******************************/ #include “http.h” void msg(char * str) { #ifdef _DEBUG cout<<str<<endl; #endif } CHttp::CHttp() { } CHttp::~CHttp() { } bool CHttp::CreateSocket() { if(WSAStartup(MAKEWORD(2,2),&m_WSADATA)==SOCKET_ERROR) { msg(“wsastartup”); ReleaseSocket(); return false; } if((m_SOCKET=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR) { msg(“socket”); ReleaseSocket(); return false; } return true; } void CHttp::ReleaseSocket() { shutdown(m_SOCKET,SD_BOTH); closesocket(m_SOCKET); WSACleanup(); } bool CHttp::Connect(const string & httpAddr,const int port) { if(! CreateSocket()) return false; if((m_HOSTENT=gethostbyname(httpAddr.c_str()))==NULL) { msg(“gethostbyname”); ReleaseSocket(); return false; } if(m_HOSTENT->h_addr_list[0]==NULL) { msg(“h_addr_list”); ReleaseSocket(); return false; } memset(&m_SOCKADDR_IN,0,sizeof(m_SOCKADDR_IN)); m_SOCKADDR_IN.sin_family=AF_INET; m_SOCKADDR_IN.sin_port=htons(port); m_SOCKADDR_IN.sin_addr.S_un.S_addr=*(ULONG *)m_HOSTENT->h_addr_list[0]; int timeOut=5000; if(::setsockopt(m_SOCKET,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeOut,sizeof(timeOut))==SOCKET_ERROR) return false; if(connect(m_SOCKET,(sockaddr *)&m_SOCKADDR_IN,sizeof(m_SOCKADDR_IN))==SOCKET_ERROR) { msg(“connect”); ReleaseSocket(); return false; } return true; } string CHttp::RecvData() { try { len=recv(m_SOCKET,buf,sizeof(buf),0); if(len==SOCKET_ERROR) return “”; buf[len]=0; return string(buf); } catch(…) { return “”; } } int CHttp::SendData(const char * str) { return send(m_SOCKET,str,strlen(str),0); } /**************************main.cpp**************************/ #pragma warning (disable:4786) #include <iostream> #include <sstream> #include <iterator> #include <vector> #include “http.h” #include “code.h” using namespace std; string StoreCookies(const string & strRecv) //从登陆接收的数据中分离出Cookie信息合并成发送的格式 { string sCookies; istringstream ssin(strRecv); string line; while(! getline(ssin,line).eof()) { if(line.find(“cookie”)!=string::npos) { int pos[2]; if((pos[0]=line.find(“\’”,0))!=string::npos && (pos[1]=line.find(“\’”,pos[0]+1))!=string::npos) { if(sCookies.length()>0) sCookies+=”;”; sCookies+=line.substr(pos[0]+1,pos[1]-pos[0]-1); } } } return sCookies; } int main() { CHttp http; http.Connect(“bbs.jlu.edu.cn”); /******************登陆BBS并提取Cookie*********************/ string login=”POST /cgi-bin/bbslogin HTTP/1.1\r\n”; login+=”Content-Type: application/x-www-form-urlencoded\r\n”; login+=”Host: bbs.jlu.edu.cn\r\n”; login+=”Content-Length: 27\r\n\r\n”; //HTTP头结束,两个”\r\n” login+=”id=luosiyong&pw=’yourpwd’\r\n\r\n”; //提交表单内容 这里pw经过了处理 http.SendData(login.c_str()); string sRecv=http.RecvData(); cout<<”login response >>>>>>\n”<<sRecv<<endl; string sCookie=StoreCookies(sRecv); //从登陆的信息提取cookie用于后面验证 /*******************发帖*************************************/ string post=”POST /cgi-bin/bbssnd?board=Arctic&u=0&r=0 HTTP/1.1\r\n”; post+=”Content-Type: application/x-www-form-urlencoded\r\n”; post+=”Host: bbs.jlu.edu.cn\r\n”; post+=”Content-Length: 50\r\n”; post+=”Cookie: \r\n\r\n”; post+=”title=测试&signature=1&text=文本!@#$^*()_+|[]‘内容\r\n”; //注意不能包含%和&符号,它们在HTTP中用于转义和变量连接 post.insert(post.find(“Cookie: “)+strlen(“Cookie: “),sCookie); //在http头中加入Cookie信息 http.SendData(post.c_str()); cout<<http.RecvData()<<endl; /*******************注销登陆**********************************/ string logout=”GET /cgi-bin/bbslogout HTTP/1.1\r\n”; logout+=”Host: bbs.jlu.edu.cn\r\n”; logout+=”Cookie: \r\n\r\n”; logout.insert(logout.find(“Cookie: “)+strlen(“Cookie: “),sCookie); http.SendData(logout.c_str()); cout<<http.RecvData()<<endl; return 0; }