国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

用VC++實(shí)現(xiàn)http代理

2019-11-17 05:16:48
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  為了幫網(wǎng)友些個(gè)用http下載動(dòng)畫的程序,臨時(shí)在網(wǎng)上翻了翻,看看有沒(méi)有利用http代理來(lái)下載的例子。結(jié)果,似乎很多人都愿意去轉(zhuǎn)載一個(gè)有頭無(wú)尾的例子,還美其名曰“我在查閱RFC文檔和相關(guān)資料后,特總結(jié)一些TCP協(xié)議穿透代理服務(wù)器的程序片斷,希望對(duì)大家有所幫助。”

  假如真的想幫助大家,為什么不說(shuō)的具體一些?

  無(wú)奈之下,自己去翻rfc文檔,找了些資料,寫了這個(gè)利用http代理來(lái)下載文件的資料

  代碼如下:

  (1)一些基本變量

SOCKET HTTPSocket; // 主socket
strUCt sockaddr_in SocketAddr; // address socket
struct sockaddr_in BindSocket; // for bind


int m_nRecvTimeout; // recieve timeout
int m_nSendTimeout; // send timeout

WSADATA wsaData;

// 要下載文件部分。似乎在BindSocket.sin_addr.s_addr = inet_addr (strHost);時(shí),只能使用ip地址,所以了。。。

// 假如誰(shuí)知道更好的方法,別忘了告訴我一下。

CString strHost="111.111.111.111 ";
CString DownLoadAddress="http://www.aitenshi.com/bbs/images/";
CString hostFile="logo.gif";
int HttpPort=80;



  (2)一些函數(shù),用來(lái)取得http頭,和獲取文件大小

int GetFileLength(char *httpHeader)
{
CString strHeader;
int local;
strHeader=(CString)httpHeader;
local=strHeader.Find("Content-Length",0);
local+=16;
strHeader.Delete(0,local);
local=strHeader.Find("/r");
strHeader.SetAt(local,'/0');

char temp[30];
strcpy(temp,strHeader.GetBuffer(strHeader.GetLength()));
return atoi(temp);
}

int GetHttpHeader(SOCKET sckDest,char *str)
{
BOOL m_bResponsed=0;
int m_nResponseHeaderSize;

if(!m_bResponsed)
{
char c = 0;
int nIndex = 0;
BOOL bEndResponse = FALSE;
while(!bEndResponse && nIndex < 1024)
{
recv(sckDest,&c,1,0);
str[nIndex++] = c;
if(nIndex >= 4)
{
if(str[nIndex - 4] == '/r' && str[nIndex - 3] == '/n'
&& str[nIndex - 2] == '/r' && str[nIndex - 1] == '/n')
bEndResponse = TRUE;
}
}
m_nResponseHeaderSize = nIndex;
m_bResponsed = TRUE;
}

return m_nResponseHeaderSize;

}


  (3)用來(lái)發(fā)送的部分

void szcopy(char* dest,const char* src,int nMaxBytes)
{
int i_cntr=0;
while ((src[i_cntr]!='/0')    (i_cntr dest[i_cntr]=src[i_cntr++];
dest[i_cntr]='/0';
}

BOOL SocketSend(SOCKET sckDest,const char* szHttp)
{

char szSendHeader[MAXHEADERLENGTH];
int iLen=strlen(szHttp);
szcopy(szSendHeader,szHttp,iLen);
if(send (sckDest ,(const char FAR *)szSendHeader ,iLen ,0)==SOCKET_ERROR)
{
closesocket(sckDest);
AfxMessageBox("Error when send");
return FALSE;
}

return TRUE;
}

BOOL SocketSend(SOCKET sckDest,CString szHttp)
{

int iLen=szHttp.GetLength();
if(send (sckDest,szHttp,iLen,0)==SOCKET_ERROR)
{
closesocket(sckDest);
AfxMessageBox("Error when send");
return FALSE;
}

return TRUE;
}


  (4)用于連接的函數(shù)

  這里是做了一些連接用的操作,分了兩種情況

  1)假如沒(méi)有使用代理,則直接連到你指定的計(jì)算機(jī)

  2)假如使用了代理,則直接連到代理

BOOL CDLAngelDlg::ConnectHttp()
{

message="正在建立連接/n";


UpdateData(TRUE);
if(m_combo=="HTTP") // m_combo 一個(gè)下拉條
{
HTTPSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
SocketAddr.sin_addr.s_addr = inet_addr (m_ProxyAddr);
SocketAddr.sin_family=AF_INET;
SocketAddr.sin_port=htons(atoi(m_Port));

struct fd_set fdSet;
struct timeval tmvTimeout={0L,0L};

FD_ZERO(&fdSet);
FD_SET(HTTPSocket, &fdSet);

if (select(0,&fdSet,NULL,NULL,&tmvTimeout)==SOCKET_ERROR)
{
closesocket(HTTPSocket);
AfxMessageBox("Error when select.");
return 0;
}


if (connect(HTTPSocket, (const struct sockaddr *)&SocketAddr, sizeof(SocketAddr))==SOCKET_ERROR)
{
message="/n代理連接失敗/n";
m_message.CleanText();
m_message.AddText(message);
return 0;
}


// 發(fā)送CONNCET請(qǐng)求令到代理服務(wù)器,用于和代理建立連接

//代理服務(wù)器的地址和端口放在m_ProxyAddr,m_Port 里面

CString temp;
char tmpBuffer[1024];
temp.Format("CONNECT %s:%s HTTP/1.1/r/nUser-Agent: MyApp/0.1/r/n/r/n",m_ProxyAddr,m_Port);
if(!SocketSend(HTTPSocket,temp))
{
message="連接代理失敗";
return 0;
}

// 取得代理響應(yīng),假如連接代理成功,代理服務(wù)器將返回200 Connection established

GetHttpHeader(HTTPSocket,tmpBuffer);
temp=tmpBuffer;
if(temp.Find("HTTP/1.0 200 Connection established",0)==-1)
{
message="連接代理失敗/n";
return 0;
}

message="代理連接完成/n";
m_message.AddText("代理連接完成/n");
return 1; // ----------〉這里是應(yīng)該注重的,連接到代理后,就可以返回了,不需要再連接網(wǎng)上的另外一臺(tái)機(jī),代理服務(wù)器會(huì)自動(dòng)轉(zhuǎn)發(fā)數(shù)據(jù),所以,連接完代理就像連接到網(wǎng)上另外一臺(tái)機(jī)一樣
}

// 這個(gè),是為了給其他代理做預(yù)備
else if(m_combo=="Socks4")
{MessageBox("請(qǐng)注重,現(xiàn)在無(wú)法使用代理功能!");}
else if(m_combo=="Socks5")
{MessageBox("請(qǐng)注重,現(xiàn)在無(wú)法使用代理功能!");}


// 假如沒(méi)有使用代理,就要連接到網(wǎng)上的另一臺(tái)機(jī)

// 預(yù)備socket
HTTPSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if (HTTPSocket==INVALID_SOCKET)
{
AfxMessageBox("Error when socket");
return 0;
}

//設(shè)置超時(shí)
struct linger zeroLinger;
zeroLinger.l_onoff = 1;
zeroLinger.l_linger = 0;
if(setsockopt(HTTPSocket,SOL_SOCKET,SO_LINGER
,(const char *)&zeroLinger
,sizeof(zeroLinger))!=0)
{
closesocket(HTTPSocket);
AfxMessageBox("Error when setscokopt(LINGER)");
return 0;
}
QQ病毒 騰訊QQ空間代碼專題 PPT教程專題 ADSL應(yīng)用面面俱到 fireworks教程專題 計(jì)算機(jī)和網(wǎng)絡(luò)技術(shù)基礎(chǔ)知識(shí) 校園網(wǎng)專題 網(wǎng)吧技術(shù)專題

  //設(shè)置接收超時(shí)
if(setsockopt(HTTPSocket,SOL_SOCKET,SO_RCVTIMEO
,(const char *)&m_nRecvTimeout
,sizeof(m_nRecvTimeout))!=0)
{
closesocket(HTTPSocket);
AfxMessageBox("Error when setsockopt(RCVTIME).");
return 0;
}

//設(shè)置發(fā)送超時(shí)
if(setsockopt(HTTPSocket,SOL_SOCKET,SO_SNDTIMEO
,(const char *)&m_nSendTimeout
,sizeof(m_nSendTimeout))!=0)
{
closesocket(HTTPSocket);
AfxMessageBox("Error when setsockopt(SNDTIMEO).");
return 0;
}


SocketAddr.sin_addr.s_addr = htonl (INADDR_ANY);
SocketAddr.sin_family=AF_INET;

// 進(jìn)行端口綁定
if (bind (HTTPSocket,
(const struct sockaddr FAR *)&SocketAddr,
sizeof(SocketAddr))==SOCKET_ERROR)
{
closesocket(HTTPSocket);
AfxMessageBox("Error when bind socket.");
return 0;
}

//預(yù)備連接

/// 預(yù)備連接信息
BindSocket.sin_addr.s_addr = inet_addr (strHost);
BindSocket.sin_family=AF_INET;
BindSocket.sin_port=htons(HttpPort);


struct fd_set fdSet;
struct timeval tmvTimeout={0L,0L};

FD_ZERO(&fdSet);
FD_SET(HTTPSocket, &fdSet);

if (select(0,&fdSet,NULL,NULL,&tmvTimeout)==SOCKET_ERROR)
{
closesocket(HTTPSocket);
AfxMessageBox("Error when select.");
return 0;
}

// 連接


if (connect(HTTPSocket, (const struct sockaddr *)&BindSocket, sizeof(BindSocket))==SOCKET_ERROR)
{
AfxMessageBox("第一次連接失敗,預(yù)備第二次連接");
if (connect(HTTPSocket
,(const struct sockaddr *)&BindSocket
,sizeof(BindSocket))==SOCKET_ERROR)
{
closesocket(HTTPSocket);
AfxMessageBox("連接失敗");
return 0;
}

}

message="連接完成/n";

return 1;
}


  (5)發(fā)送http請(qǐng)求,為下載數(shù)據(jù)進(jìn)行預(yù)備

int CDLAngelDlg::SendHttpHeader()
{
//進(jìn)行下載

CString temp;
BOOL bReturn;
char tmpBuffer[MAXBLOCKSIZE];


///第1行:方法,請(qǐng)求的路徑,版本
temp="GET "+DownLoadAddress+hostFile+" HTTP/1.0/r/n";
bReturn=SocketSend(HTTPSocket,temp);
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}


///第2行:主機(jī)
temp="Host "+strHost+"/r/n";
bReturn=SocketSend(HTTPSocket,temp);
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}


///第3行:接收的數(shù)據(jù)類型
bReturn=SocketSend(HTTPSocket,"Accept: */*/r/n");
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}


///第4行:
temp=DownLoadAddress;
temp.Insert(0,"Referer ");
temp+="/r/n";
bReturn=SocketSend(HTTPSocket,temp);
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}


///第5行:瀏覽器類型

bReturn=SocketSend(HTTPSocket,"User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt; DTS Agent;)/r/n");
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}

///第6行:連接設(shè)置,保持
// SocketSend(HTTPSocket,"Connection:Keep-Alive/r/n");

///第7行:Cookie.

bReturn=SocketSend(HTTPSocket,"Cache-Control: no-cache/r/n");
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}


bReturn=SocketSend(HTTPSocket,"Proxy-Connection: Keep-Alive/r/n");
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}

/// 續(xù)傳

Range是要下載的數(shù)據(jù)范圍,對(duì)續(xù)傳很重要
if(continueFlag)
{
temp.Format("Range: bytes=%d- /r/n",conLength);
bReturn=SocketSend(HTTPSocket,temp);
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}
}


///最后一行:空行
bReturn=SocketSend(HTTPSocket,"/r/n");
if(!bReturn)
{
message="發(fā)送請(qǐng)求失敗";
return 0;
}

///取得http頭
int i;
i=GetHttpHeader(HTTPSocket,tmpBuffer);
if(!i)
{
message="獲取HTTP頭出錯(cuò)";
return 0;
}

//假如取得的http頭含有404等字樣,則表示連接出問(wèn)題
temp=tmpBuffer;
if(temp.Find("404")!=-1)
{

return 0;
}

// 得到待下載文件的大小

filelength=GetFileLength(tmpBuffer);

return 1;
}


  這樣,就連接到網(wǎng)上的另一臺(tái)機(jī)了,如何下載數(shù)據(jù),不用多說(shuō)了吧

while((num!=SOCKET_ERROR) && (num!=0))
{
num=recv (HTTPSocket
,(char FAR *)tmpBuffer
,(MAXBLOCKSIZE-1)
,0);


file.Write(tmpBuffer,num);

if(ExitFlag)
{
file.Close();
closesocket(HTTPSocket);

DownComplete=1;

m_message.CleanText();
m_message.ShowColorText(RGB(128,128,0),DLCompleteMes);

m_progress.ShowWindow(SW_HIDE);
m_stopDownload.ShowWindow(SW_HIDE);
_endthread();
}

}


  基本就是這樣了,本人寫程序水平也不是很高,這個(gè)程序還是可以用的。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 张北县| 黎川县| 盘锦市| 宁晋县| 常宁市| 深圳市| 井冈山市| 涟源市| 肥乡县| 神农架林区| 开鲁县| 延长县| 柏乡县| 松原市| 子洲县| 澎湖县| 寿宁县| 锡林浩特市| 法库县| 锡林郭勒盟| 克拉玛依市| 沧源| 中宁县| 贡嘎县| 乐山市| 中江县| 嘉荫县| 大洼县| 楚雄市| 邵武市| 崇州市| 清涧县| 翼城县| 梁平县| 静海县| 北票市| 乌鲁木齐县| 昌黎县| 中西区| 上犹县| 南宫市|