/***************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;
}
posted on 2011-05-24 19:51  °ι 、曲 终  阅读(1659)  评论(1编辑  收藏  举报