http代理请求头 需要在请求中填写户名和密码

xiaoli2006 2011-06-08 01:46:18
现在需要用http请求去网络上抓取一些页面,用的是C++语言。但是公司用的是代理服务器,需要填写用户名和密码才能上网。请问请求头的格式是怎样的,如果可以贴一下代码。读了一会儿RFC也是云里雾里的,谢谢大侠们!!!

附:这是之前找的代码,虽然也有代理,但是没有用用户名和密码,不知道怎么改

// http.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <afx.h>
#include <winsock2.h> //header
#pragma comment (lib, "ws2_32.lib") //lib

//  (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);时,只能使用ip地址,所以了。。。

// 如果谁知道更好的方法,别忘了告诉我一下。

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


//   (2)一些函数,用来取得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] == ''
&& str[nIndex - 2] == '\r' && str[nIndex - 1] == '')
bEndResponse = TRUE;
}
}
m_nResponseHeaderSize = nIndex;
m_bResponsed = TRUE;
}

return m_nResponseHeaderSize;

}


//  (3)用来发送的部分

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)用于连接的函数

  这里是做了一些连接用的操作,分了两种情况

  1)如果没有使用代理,则直接连到你指定的计算机

  2)如果使用了代理,则直接连到代理
*/
BOOL CDLAngelDlg::ConnectHttp()
{

string message="正在建立连接";


UpdateData(TRUE);
if(m_combo=="HTTP") // m_combo 一个下拉条
{
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="代理连接失败";
m_message.CleanText();
m_message.AddText(message);
return 0;
}


// 发送CONNCET请求令到代理服务器,用于和代理建立连接

//代理服务器的地址和端口放在m_ProxyAddr,m_Port 里面

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

// 取得代理响应,如果连接代理成功,代理服务器将返回200 Connection established

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

message="代理连接完成";
m_message.AddText("代理连接完成");
return 1; // ----------〉这里是应该注意的,连接到代理后,就可以返回了,不需要再连接网上的另外一台机,代理服务器会自动转发数据,所以,连接完代理就像连接到网上另外一台机一样
}

// 这个,是为了给其他代理做准备
else if(m_combo=="Socks4")
{MessageBox("请注意,现在无法使用代理功能!");}
else if(m_combo=="Socks5")
{MessageBox("请注意,现在无法使用代理功能!");}


// 如果没有使用代理,就要连接到网上的另一台机// 准备socket
HTTPSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

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

//设置超时
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;
}
  //设置接收超时
if(setsockopt(HTTPSocket,SOL_SOCKET,SO_RCVTIMEO
,(const char *)&m_nRecvTimeout
,sizeof(m_nRecvTimeout))!=0)
{
closesocket(HTTPSocket);
AfxMessageBox("Error when setsockopt(RCVTIME).");
return 0;
}

//设置发送超时
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;

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

//准备连接

/// 准备连接信息
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("第一次连接失败,准备第二次连接");
if (connect(HTTPSocket
,(const struct sockaddr *)&BindSocket
,sizeof(BindSocket))==SOCKET_ERROR)
{
closesocket(HTTPSocket);
AfxMessageBox("连接失败");
return 0;
}

}

message="连接完成";

return 1;
}


//   (5)发送http请求,为下载数据进行准备

int CDLAngelDlg::SendHttpHeader()
{
//进行下载

CString temp;
BOOL bReturn;
char tmpBuffer[MAXBLOCKSIZE];///第1行:方法,请求的路径,版本
temp="GET "+DownLoadAddress+hostFile+" HTTP/1.0\r";
bReturn=SocketSend(HTTPSocket,temp);
if(!bReturn)
{
message="发送请求失败";
return 0;
}


///第2行:主机
temp="Host "+strHost+"\r";
bReturn=SocketSend(HTTPSocket,temp);
if(!bReturn)
{
message="发送请求失败";
return 0;
}


///第3行:接收的数据类型
bReturn=SocketSend(HTTPSocket,"Accept: */*\r");
if(!bReturn)
{
message="发送请求失败";
return 0;
}


///第4行:
temp=DownLoadAddress;
temp.Insert(0,"Referer ");
temp+="\r";
bReturn=SocketSend(HTTPSocket,temp);
if(!bReturn)
{
message="发送请求失败";
return 0;
}


///第5行:浏览器类型

bReturn=SocketSend(HTTPSocket,"User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt; DTS Agent;)\r");
if(!bReturn)
{
message="发送请求失败";
return 0;
}

///第6行:连接设置,保持
// SocketSend(HTTPSocket,"Connection:Keep-Alive\r");

///第7行:Cookie.

bReturn=SocketSend(HTTPSocket,"Cache-Control: no-cache\r");
if(!bReturn)
{
message="发送请求失败";
return 0;
}


bReturn=SocketSend(HTTPSocket,"Proxy-Connection: Keep-Alive\r");
if(!bReturn)
{
message="发送请求失败";
return 0;
}

/// 续传

//Range是要下载的数据范围,对续传很重要
if(continueFlag)
{
temp.Format("Range: bytes=%d- \r",conLength);
bReturn=SocketSend(HTTPSocket,temp);
if(!bReturn)
{
message="发送请求失败";
return 0;
}
}


...全文
832 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
luciferisnotsatan 2011-06-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xiaoli2006 的回复:]

这个必须要要用在程序中实现,这是一个系统的一部分,要请求页面,分析页面,再处理一下。现在的问题是公司是代理服务器,对请求头格式不了解。查了下RFC也不知所云的。
引用 1 楼 bdmh 的回复:
你用wpe等抓包工具,在你从网络上正常登陆的情况下,抓包看看头信息
[/Quote]
1楼的意思是,用抓包工具看看浏览器设置代理后,是怎么给代理发用户名/密码的。然后抄一下就是了。
xiaoli2006 2011-06-08
  • 打赏
  • 举报
回复
真没有人知道吗,不会吧,如果经常用的话应该很简单吧,我才开始用,所以不会啊
xiaoli2006 2011-06-08
  • 打赏
  • 举报
回复
没有人知道吗,顶一下
xiaoli2006 2011-06-08
  • 打赏
  • 举报
回复
其实我主要关注的代码只有一个函数:
/*   (4)用于连接的函数

  这里是做了一些连接用的操作,分了两种情况

  1)如果没有使用代理,则直接连到你指定的计算机

  2)如果使用了代理,则直接连到代理
*/
BOOL CDLAngelDlg::ConnectHttp()
科比布莱恩特 2011-06-08
  • 打赏
  • 举报
回复
这代码,也忒长了。
xiaoli2006 2011-06-08
  • 打赏
  • 举报
回复
这个必须要要用在程序中实现,这是一个系统的一部分,要请求页面,分析页面,再处理一下。现在的问题是公司是代理服务器,对请求头格式不了解。查了下RFC也不知所云的。
[Quote=引用 1 楼 bdmh 的回复:]
你用wpe等抓包工具,在你从网络上正常登陆的情况下,抓包看看头信息
[/Quote]
bdmh 2011-06-08
  • 打赏
  • 举报
回复
你用wpe等抓包工具,在你从网络上正常登陆的情况下,抓包看看头信息

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧