您现在的位置: 天下网吧 >> 网吧天地 >> 天下码农 >> 微信小程序 >> 正文

用VC++实现http代理

2008-11-6来自网络佚名
 为了帮网友些个用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("请注意,现在无法使用代理功能!");}


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

欢迎访问最专业的网吧论坛,无盘论坛,网吧经营,网咖管理,网吧专业论坛 https://bbs.txwb.com

关注天下网吧微信/下载天下网吧APP/天下网吧小程序,一起来超精彩

本文来源:来自网络 作者:佚名

声明
声明:本站所发表的文章、评论及图片仅代表作者本人观点,与本站立场无关。若文章侵犯了您的相关权益,请及时与我们联系,我们会及时处理,感谢您对本站的支持!联系邮箱:support@txwb.com,系统开号,技术支持,服务联系QQ:1175525021本站所有有注明来源为天下网吧或天下网吧论坛的原创作品,各位转载时请注明来源链接!
天下网吧 网吧天下