电脑软硬件应用网
当前位置: 电脑软硬件应用网 > 设计学院 > 网络编程 > C语言 > 正文
用VC++实现http代理
用VC++实现http代理
2008-8-4 0:44:21  文/佚名   出处:站长网   

  为了帮网友些个用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] == ''
    && 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()
    {

    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("请注意,现在无法使用代理功能!");}


    // 如果没有使用代理,就要连接到网上的另一台机

[1] [2] 下一页

  • 上一篇文章:

  • 下一篇文章:
  • 最新热点 最新推荐 相关文章
    用C语言实现的闹钟程序
    C#实现Windows关机的代码
    用动态规划法求组和数的算法
    循环结构程序具有哪3个组成部分?
    const成员函数有什么特点?
    c语言求平均分程序
    一道关于指针的C语言题
    C语言求3个整数的最大公约数
    BM模式匹配算法C语言实现
    从键盘输入任意5个4位整数存入数组a…
    关于45IT | About 45IT | 联系方式 | 版权声明 | 网站导航 |

    Copyright © 2003-2011 45IT. All Rights Reserved 浙ICP备09049068号