奇趣技术网 收藏本站
设为主页
商务合作
首页 新闻中心 行业动态 软件新闻 安全资讯 病毒预警 漏洞发布 操作系统 Dos Win9x Win2000 WinXP Win2003 WinVista Linux Unix
数据库 DB2 Access MSSQL MySQL Oracle Sybase 编程技术 ASP PHP JSP CGI/Perl XML .Net C/C++/C# VB VC Delphi Java 汇编
安全技术 安全教学 工具介绍 漏洞利用 病毒防范 入侵检测 防火墙 安全防范 汉化破解 攻击实例 加密解密 技术论坛
中华网络安全联盟 >> 程序开发 >> VC >> 用VC++实现http代理
程序开发
Asp
PHP
JSP
CGI/Perl
XML
.Net
C/C++/C#
Visual Basic
Visual C++
Delphi
Java
汇编语言
  • VC中利用多线程技术实

  • 利用OpenGL实现三维绘

  • 基于Visual C++的Wins

  • 基于Visual C++6.0的D

  • Visual C++ MFC 中常用

  • 在MFC下如何定义全局变

  • 使用MFC在应用程序中嵌

  • VC++中进程与多进程管

  • 用VC++实现http代理
    字体:

    中华网络安全联盟    作者:佚名    来源:网络转载    时间:2006-3-22

        为了帮网友些个用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 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;
    }

    字体:
     
    设为主页 收藏本站 联系我们 友情连接 商务合作 网友留言
    Copyright©2006-2008 中华网络安全联盟 All rights reserved.