动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C/C++教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ C/C++教程 ]的信息



本月文章推荐
.偶写的链表、堆栈、队列的集合操.
.数据结构算法集---C++语言实现.
.C语言教程第六章:指针.
.试一下 moving ball.
.C++ 继承性应用实例—日期和时间.
.用BCB3.0制作桌面动画.
.Linux 下面使用 mtrace 来检查一.
.C++习题与解析(类和对象-02).
.巧算星期几.
.Windows文件保护的应用.
.取得系统中网卡MAC地址的三种方法.
.C++ Builder 初学问与答(六).
.让CppWebBrowser响应回车健.
.C++中运算符优先级的学习注解.
.庆祝20岁生日: C++图书热点观察.
.Windows编程基础 - 设.
.C/C++:如何在程序中加载JPG图片?.
.旋转的立体椭球(效果非常好).
.高质量C++/C编程指南 --&nb.
.new和delete导致的内存分配问题详.

透过代理看世界 用VC++实现http代理

发表日期:2008-3-8 |


  为了帮网友些个用http下载动画的程序,临时在网上翻了翻,看看有没有利用http代理来下载的例子。结果,似乎很多人都愿意去转载一个有头无尾的例子,还美其名曰“我在查阅RFC文档和相关资料后,特总结一些TCP协议穿透代理服务器的程序片断,希望对大家有所帮助。”
  假如真的想帮助大家,为什么不说的具体一些?   无奈之下,自己去翻rfc文档,找了些资料,写了这个利用http代理来下载文件的资料   代码如下:   (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] == '\n'
                             && str[nIndex - 2] == '\r' && str[nIndex - 1] == '\n')
                            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<nMaxBytes))
                    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()
{  message="正在建立连接\n";
  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="\n代理连接失败\n";
                       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\r\nUser-Agent: MyApp/0.1\r\n\r\n",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="连接代理失败\n";
                       return 0;
            }             message="代理连接完成\n";
            m_message.AddText("代理连接完成\n");
            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="连接完成\n";
 
 return 1;
}   (5)发送http请求,为下载数据进行预备

int CDLAngelDlg::SendHttpHeader()
{
//进行下载  CString temp;
 BOOL bReturn;
 char tmpBuffer[MAXBLOCKSIZE];
///第1行:方法,请求的路径,版本
 temp="GET "+DownLoadAddress+hostFile+" HTTP/1.0\r\n";
 bReturn=SocketSend(HTTPSocket,temp);
 if(!bReturn)
 {
  message="发送请求失败";
  return 0;
 }
///第2行:主机
 temp="Host "+strHost+"\r\n";
 bReturn=SocketSend(HTTPSocket,temp);
 if(!bReturn)
 {
            message="发送请求失败";
            return 0;
 }
///第3行:接收的数据类型
 bReturn=SocketSend(HTTPSocket,"Accept: */*\r\n");
   if(!bReturn)
 {
            message="发送请求失败";
            return 0;
 }
///第4行:
 temp=DownLoadAddress;
 temp.Insert(0,"Referer ");
 temp+="\r\n";
 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\n");
 if(!bReturn)
 {
            message="发送请求失败";
            return 0;
 }
///第6行:连接设置,保持
// SocketSend(HTTPSocket,"Connection:Keep-Alive\r\n"); ///第7行:Cookie.  bReturn=SocketSend(HTTPSocket,"Cache-Control: no-cache\r\n");
 if(!bReturn)
 {
            message="发送请求失败";
            return 0;
 }
 bReturn=SocketSend(HTTPSocket,"Proxy-Connection: Keep-Alive\r\n");
 if(!bReturn)
 {
            message="发送请求失败";
            return 0;
 } /// 续传 Range是要下载的数据范围,对续传很重要
 if(continueFlag)
 {
            temp.Format("Range: bytes=%d- \r\n",conLength);
            bReturn=SocketSend(HTTPSocket,temp);
            if(!bReturn)
            {
             message="发送请求失败";
             return 0;
            }
 } ///最后一行:空行
 bReturn=SocketSend(HTTPSocket,"\r\n");
 if(!bReturn)
 {
            message="发送请求失败";
            return 0;
 } ///取得http头
 int i;
 i=GetHttpHeader(HTTPSocket,tmpBuffer);
 if(!i)
 {
            message="获取HTTP头出错";
            return 0;
 } //假如取得的http头含有404等字样,则表示连接出问题
 temp=tmpBuffer;
 if(temp.Find("404")!=-1)
 {   return 0;
 } // 得到待下载文件的大小  filelength=GetFileLength(tmpBuffer);  return 1;
}   这样,就连接到网上的另一台机了,如何下载数据,不用多说了吧 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();
   }  }   基本就是这样了,本人写程序水平也不是很高,这个程序还是可以用的。 更多文章 更多内容请看HTTP协议专题,或

上一篇:Delphi中带缓存的数据更新技术 人气:373
下一篇:绝对经典 C++初学者必看的50个建议 人气:225
浏览全部C/C++的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-6 飞天论坛FTBBS ASP v6.3 Build 0
2008-7-6 飞天论坛FTBBS ASP v6.3 Build 0
2008-7-6 飞天论坛FTBBS ASP v6.8 Build 0
2008-7-6 讯息内容管理系统 v2.1
2008-7-6 三五电影程序 v2.0
2008-7-6 神鹰腾讯小说小偷 v3.0
2008-7-6 EasyIDE Framework v1.0 Build 2
2008-7-6 品告CMS系统(电影版) v0.9
2008-7-6 QQ自动登录器 C# 源码 v1.0
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 GoodCalculator2.0版固件计算器
2008-7-5 RepoName源地址搜索工具 v1.21b
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 TouchCopy多媒体管理软件 v3.13完
2008-7-5 VideosTone视频铃声 v1.1汉化破解
2008-7-5 TouchPad触摸板 v4.44破解版
2008-7-5 VideosTone破解补丁 v1.0
2008-7-5 Feeds GoogleReader客户端 v0.4.3


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報