1. 程式人生 > >C/C++程式實現通過http代理訪問網頁內容

C/C++程式實現通過http代理訪問網頁內容

公司通過代理上網,C程式直接通過發http請求不能獲取網頁內容,故實現了下通過代理訪問http網頁的一個測試程式。

程式很簡單,有幾個重點

  1. 先通過socket直接連線代理伺服器

  2. 向代理伺服器傳送HTTP的CONNECT標頭,格式為CONNECT www.baidu.com:80 HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n

    其中%s處替換為user:passwd的base64編碼

  3. 鑑權通過後 send請求就ok,注意此處和不用代理的區別是 GET後面的地址要http://www.baidu.com 而不能是www.baidu.com

  4. 這是個測試程式,目的只是說明實現過程,我測試的可以收到返回報文,也有不完善的地方,比如接收不全。

程式碼如下:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string>

//以下六個引數改為自己需要的即可
const char *proxyAddr="10.1.1.2";
const int proxyPort = 8080;
const char *user="domain\\name";
const char *passwd="kklklkl";
const char *desthost="www.baidu.com";
const int destport=80;
static void to64frombits(unsigned char *out, const unsigned char *in, int inlen);

int main() {
	int sock_fd;
	struct sockaddr_in addr;
	struct hostent *hptr;
	char str[32];
	
	/*	if((hptr = gethostbyname(proxyAddr)) == NULL)
	    {
	        printf(" gethostbyname error for host:%s\n", proxyAddr);
	        return 0; 
	    }
	*/    
	if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		perror("socket() fail.");
	
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(proxyPort);
	inet_aton(proxyAddr, &addr.sin_addr);
	//memcpy(&addr.sin_addr.s_addr,hptr->h_addr,sizeof(addr.sin_addr.s_addr));
	//printf("proxy ip=%s\n",inet_ntop(hptr->h_addrtype,hptr->h_addr,str,sizeof(str)));
	if (connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		close(sock_fd);
		perror("connect() fail.");
	}
	printf("-=-=-=-=-=-=-=We have connect the proxy ok!!!!-=-=-=-=-=-=-=\n");
	char tmp[10240+1];
	char authstr[10240+1];
	memset(tmp,0x0,sizeof(tmp));
	memset(authstr,0x0,sizeof(authstr));
	sprintf(tmp,"%s:%s",user,passwd);
	printf("=======%s",tmp);
	to64frombits((unsigned char*)authstr,(unsigned char*)tmp,strlen(tmp));
	printf("--=====%s",authstr);
	snprintf(tmp,sizeof(tmp),"CONNECT %s:%d HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n", desthost, destport, authstr);
	send(sock_fd, tmp, strlen(tmp), 0);
	printf("-=-=-=-=-=wait for recv-=-=-=-=-=\n");
	
	memset(tmp,0x0,sizeof(tmp));
	recv(sock_fd, tmp, sizeof(tmp), 0);
	printf("recv=%s",tmp);
	//通過代理get,此處的url一定要是全路徑帶上http://,否則訪問不到
	snprintf(tmp,sizeof(tmp),"GET %s HTTP/1.0\r\n", "http://www.baidu.com/");
	strcpy(tmp+strlen(tmp),"Accept:*/*\r\n");
	strcpy(tmp+strlen(tmp),"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
	strcpy(tmp+strlen(tmp),"Accept-Language:zh-cn\r\n");
	strcpy(tmp+strlen(tmp),"Connection:close\r\n\r\n");
	send(sock_fd, tmp, strlen(tmp), 0);
	memset(tmp,0x0,sizeof(tmp));
	sleep(5);
	recv(sock_fd, tmp, sizeof(tmp), 0);
	printf("recv2=%s",tmp);
	close(sock_fd);
	return 0;
}

//base64編碼函式
static void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
{
	const char base64digits[] =
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	for (; inlen >= 3; inlen -= 3)
	{
		*out++ = base64digits[in[0] >> 2];
		*out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
		*out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
		*out++ = base64digits[in[2] & 0x3f];
		in += 3;
	}
	if (inlen > 0)
	{
		unsigned char fragment;
		*out++ = base64digits[in[0] >> 2];
		fragment = (in[0] << 4) & 0x30;
		if (inlen > 1)
		fragment |= in[1] >> 4;
		*out++ = base64digits[fragment];
		*out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
		*out++ = '=';
	}
	*out = '\0';
}
測試結果:

測試結果:

[@dev1 myfile]$ ./proxy_test 

-=-=-=-=-=-=-=We have connect the proxy ok!!!!-=-=-=-=-=-=-=

=======test:1111132%--=====YdlsdfdiaDp6YmgyNDI3MDY1JQ==-=-=-=-=-=wait for recv-=-=-=-=-=

recv=HTTP/1.0 200 Connection established

recv2=HTTP/1.1 200 OK

Date: Wed, 06 Nov 2013 10:15:13 GMT

Server: Apache

P3P: CP=" OTI DSP COR IVA OUR IND COM "

P3P: CP=" OTI DSP COR IVA OUR IND COM "

Set-Cookie: BAIDUID=8F0C54DC13B905C0FA9EFD43B9D053C1:FG=1; expires=Thu, 06-Nov-14 10:15:13 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1

Set-Cookie: BAIDUID=8F0C54DC13B905C09E3548EFD4211EBA:FG=1; expires=Thu, 06-Nov-14 10:15:13 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1

Last-Modified: Mon, 31 Dec 2012 10:42:36 GMT

ETag: "1cdb-4d223abde3f00"

Accept-Ranges: bytes

Content-Length: 7387

Cache-Control: max-age=1

Expires: Wed, 06 Nov 2013 10:15:14 GMT

Vary: Accept-Encoding,User-Agent

Connection: Close

Content-Type: text/html

<!doctype html><html><head><meta http-equiv="Content-Type" content="text/html;charset=gb2312"><title>百度一下,你就知道      </title><style>html{overflow-y:auto}body{font:12px arial;text-align:center;background:#fff}body,p,form,ul{margin:0;padding:0}body,form,#fm{position:relative}td{text-align:left}img{border:0}a{color:#00c}a:active{color:#f60}#u{padding:7px 10px 3px 0;text-align:right}#m{width:680px;margin:0 auto}#nv{font-size:16px;margin:0 0 4px;text-align:left;text-indent:117px}#nv a,#nv b,.btn,#lk{font-size:14px}#fm{padding-left:90px;text-align:left}#kw{width:404px;height:22px;padding:4px 7px;padding:6px 7px 2px\9;font:16px arial;background:url(http://www.baidu.com/img/i-1.0.0.png) no-repeat -304px 0;_background-attachment:fi[@dev1 myfile]$



相關推薦

C/C++程式實現通過http代理訪問網頁內容

公司通過代理上網,C程式直接通過發http請求不能獲取網頁內容,故實現了下通過代理訪問http網頁的一個測試程式。 程式很簡單,有幾個重點 先通過socket直接連線代理伺服器 向代理伺服器傳送HTTP的CONNECT標頭,格式為CONNECT www.bai

C# webBrowser 通過代理訪問網頁

改變webBrowser1的代理 程式碼 #region 改變代理 [DllImport("wininet.dll", SetLastError = true)] private static extern bool InternetSe

C#/WPF程式實現軟體開機自動啟動的兩種方法

C#/WPF程式實現軟體開機自動啟動的兩種方法 方法一:將軟體的快捷方式建立到計算機的自動啟動目錄下(不需要管理員許可權) 1.必要引用 using System; using System.Collections.Generic; using System.Linq; using Sy

C#/WPF程式實現軟體開機自動啟動的兩種常用方法

C#/WPF/WinForm/.NET程式程式碼實現軟體程式開機自動啟動的兩種常用方法函式的示例與例項帶詳細註釋 方法一:將軟體的快捷方式建立到計算機的自動啟動目錄下(不需要管理員許可權) 1.必要引用 using System; using System.Collections.Gen

Python 通過ISA 代理訪問網際網路報錯 HTTP Error 407

urllib2.HTTPError: HTTP Error 407: Proxy Authentication Required ( The ISA Server requires authorization to fulfill the request. Access to

c語言程式實現對素數的判斷

題目: 輸出1-N之間的所有素數 要求: 為了便於觀察結果,在控制檯裡每一行輸出5個數,並且這5個數之間以空格作為分隔 思路: 首先要知道什麼是素數以及如何判斷一個數是不是素數,素數就是除了1和它自身外,沒法被其他自然數整除的數;知道怎樣判斷素數之後就可以嘗試用C語

C語言程式實現十進位制轉換為二進位制

題目: 寫一個函式,輸入一個10進位制數,輸出它的2進位制,例如:輸入9,輸出1001 思路: 十進位制數轉換為其他進位制時,轉換成幾進位制就除以幾進位制求餘。 程式碼: #include "stdio.h" #define N 100 int main() {

內網服務器通過Squid代理訪問外網

-c etc mach rmi port 圖片 ins machine determine 環境說明   項目整體需部署Zabbix監控並配置微信報警,而Zabbix Server並不能訪問外網,故運維小哥找了臺能訪問外網的服務器做Suqid代理,Zabbix Serve

proxyme——java NIO實現http代理,支援https

proxyme 一個http代理 使用java NIO的http代理。支援https。建議不要再chrome上使用本代理,因為chrome本身會請求很多谷歌的api,結果被牆住了,又只有兩個執行緒,導致其他都被阻塞,很尷尬。 之前也打算做過這個東西,結果做出來的有點缺陷(現在想可能是

【轉】通過HTTP服務訪問FTP伺服器檔案(配置nginx+ftp伺服器)

1.前提     已安裝配置好nginx+ftp服務 2.配置Nginx 伺服器     2.1進入nginx 配置檔案目錄: cd  /usr/local/nginx/conf vim  nginx.conf         2.2 修改配置檔案:有兩種

Netty實現簡單HTTP代理伺服器

自上次使用Openresty+Lua+Nginx的來加速自己的網站,用上了比較時髦的技術,感覺算是讓自己的網站響應速度達到極限了,直到看到了Netty,公司就是打算用Netty來替代Openresty這一套,所以,自己也學了好久,琢磨了好一趟才知道怎麼用,現在用來寫一套HTTP代理伺服器吧,之後再測試一下效能

關於C# 使用Xpath路徑(HtmlAgilityPack)對網頁內容查詢獲取的方法。(程式為.ashx的一般處理程式)

先貼程式碼: using System; using System.Web; using Newtonsoft.Json; using System.Net; using System.IO; using System.Text; using System.Text.Reg

Exchange2010 升級到 2016,2010用戶無法通過2016代理訪問郵箱,導致連接失敗。

-o anywhere out 功能 自動 hang 導致 chang chan 環境說明: 1臺AD和證書,4臺2010 前後端(NLB和DAG),2臺2016全角色。問題:當郵件流切換到2016後 原本在2010上的郵箱無法通過OUTLOOK連接,但是可以自動發現並配置

java通過Http請求訪問網路圖片或檔案返回byte陣列的兩種方式

第一種方式,使用HttpURLConnection 使用HttpURlConnection傳送一個get請求,開啟一個連線,從連接獲取到流,將流轉成byte陣列 /** * 發起Get請求 * * @param urlStr * @

淺談外網通過反向代理訪問內網資源時的許可權保護

標題可能有些繞口,意思就是我在外網要訪問內網一資源(比如網站)時需要身份驗證,只有通過身份驗證才能訪問,這個該如何實現? 其實這是一朋友問我的一個問題,需求就是: 領導在外出差,要通過企業微信訪問內網資源,而這個資源又是高度保密的,不能隨便讓別人看到,公司又不提供VPN等工

https 通過Fiddler代理訪問 (一)

在 https demo的基礎上新增程式碼 System.setProperty("https.proxyHost", "127.0.0.1"); System.setProperty("https.proxyPort", "8888"); 檢驗伺服器端證書相關的

關於通過http請求訪問Linux下的ftp的問題以及解決辦法

今天在學習ssm商城的時候安裝好了虛擬機器,裝好了CentOS,配置好了NGINX伺服器,也配置好了Linux自帶的ftp,但是通過http訪問的時候卻不能實現。情況如下:我使用的“FileZilla”

weblogic 啟動專案失敗,JMS 佇列通過http 方式訪問

開發十年,就只剩下這套架構體系了! >>>   

06: HTTP服務基礎 網頁內容訪問 部署動態網站 總結和答疑

Top NSD ENGINEER DAY06 案例1:獨立Web站點的快速部署 案例2:虛擬Web主機的部署 案例3:配置網頁內容訪問 案例4:使用自定Web根目錄 案例5:部署並測試WSGI站點 1 案例1:獨立Web站點的快速部署 1.1

VC++6.0 通過HTTP方式獲取網頁 OpenURL

// 顯示圖片, lpstrImgUrl 為圖片URL地址,hWnd 為視窗控制代碼   HRESULT Utils::ShowPic(char*lpstrImgUrl,HWND hWnd)    {      HDC hDC_Temp=GetDC(hWnd);          IPicture *pPi