Ejemplo n.º 1
0
    // 功能:获取下载文件的大小
    // 参数:url - 网络URL地址
    //       nFileSize - 输出文件的大小
    // 返回值:返回true表示得到了文件的大小,URL地址有效; 返回false表示无法得到文件的信息
    // 说明:这个接口是阻塞模式的,请不要在主线程调用
    static public bool  GetDownFileSize(string url, out int nOutFileSize, long nRandSeed = 0)
    {
        nOutFileSize = 0;

        CHttp  http = new CHttp(nRandSeed);
        string szServerIP = string.Empty, szObj = string.Empty;
        int    nPort = 80;

        http.ParseURL(url, ref szServerIP, ref szObj, ref nPort);

        string szAnswer = string.Empty;

        if (!http.QueryFile(ref szAnswer, szServerIP, nPort, szObj, 0, 1, false))
        {
            http.Close();
            return(false);
        }
        int nDownSize = 0, nFileSize = 0;

        if (!http.AnlyseFileLengthFromAnswer(szAnswer, ref nDownSize, ref nFileSize))
        {
            http.Close();
            return(false);
        }
        http.Close();
        nOutFileSize = nFileSize;
        return(true);
    }
Ejemplo n.º 2
0
    bool DownPart(CHttp http, string url, int nFileOffset, int nDownSize, int nFileSize, DownResFile resFile)
    {
        // 调用Http下载的代码
        nDownSize = http.PrepareDown(url, nFileOffset, nDownSize, nDownSize == 0);
        if (nDownSize <= 0)
        {
            Debug.LogError("文件下载失败,url:" + url + "(" + nFileOffset + "-" + nDownSize + ")");
            return(false);
        }

        // 将下载的内容提交到写线程
        byte[] szTempBuf    = null;
        int    nCurDownSize = 0;
        int    nRecTotal    = 0;
        int    nRecLen      = 0;
        int    nOffset      = 0;

        nCurDownSize = nDownSize > 4096 ? 4096 : nDownSize;
        MemBlock pBlock = AllockBlock(url, nFileOffset, nCurDownSize, nFileSize);  // 从内存池中取一个4K的内存片

        while (nDownSize > 0 && !m_bNeedStop)
        {
            // 必要的话,在这里添加限速功能或限制接收速度的功能,以免网速太快,导致一秒内分配太多内存
            //LimitSpeed();
            nRecLen = http.FastReceiveMax(ref szTempBuf, ref nOffset, 4096 - nRecTotal);
            if (nRecLen > 0)
            {
                OnReceive(nRecLen);  // 统计下载的流量
                Array.Copy(szTempBuf, nOffset, pBlock.data, nRecTotal, nRecLen);
                nRecTotal += nRecLen;
                // 如果当前块接收满了
                if (nRecTotal >= nCurDownSize)
                {
                    pBlock.resFile = resFile;
                    PushWrite(pBlock);// 提交写文件
                    nRecTotal    = 0;
                    nDownSize   -= nCurDownSize;
                    nFileOffset += nCurDownSize;
                    nCurDownSize = nDownSize > 4096 ? 4096 : nDownSize;
                    // 必要的话,加上限额等待
                    if (nCurDownSize > 0)
                    {
                        WaitBlock(1024 * 1024);                                          // 检测当前内存池分配的总量,超过就挂起
                        pBlock = AllockBlock(url, nFileOffset, nCurDownSize, nFileSize); // 从内存池中取一个4K的内存片
                    }
                }
            }
            else
            {
                return(false); // 文件读取失败,可能是网络出问题了
            }
        }
        return(true);
    }
Ejemplo n.º 3
0
    // 功能:下载整个文件
    // 说明:这个接口是阻塞模式的,请不要在主线程调用
    static public bool DownFile(string url, out byte[] szFileData, int nDownOffset = 0, int nNeedDownSize = 0, long nRandSeed = 0, LPOnReceiveDownFile lpReceiveFunc = null)
    {
        szFileData = null;
        CHttp  http = new CHttp(nRandSeed);
        string szServerIP = string.Empty, szObj = string.Empty;
        int    nPort = 80;

        http.ParseURL(url, ref szServerIP, ref szObj, ref nPort);

        string szAnswer = string.Empty;

        if (!http.QueryFile(ref szAnswer, szServerIP, nPort, szObj, nDownOffset, nNeedDownSize, nNeedDownSize <= 0))
        {
            http.Close();
            return(false);
        }
        int nDownSize = 0, nFileSize = 0;

        if (!http.AnlyseFileLengthFromAnswer(szAnswer, ref nDownSize, ref nFileSize))
        {
            http.Close();
            return(false);
        }
        nDownSize = nFileSize;
        byte[] szTempBuf = null;

        szFileData = new byte[nFileSize];

        int nRecTotal = 0;
        int nRecLen   = 0;
        int nOffset   = 0;

        while (nRecTotal < nDownSize)
        {
            nRecLen = http.FastReceiveMax(ref szTempBuf, ref nOffset);
            // 写入文件吧
            if (nRecLen > 0)
            {
                if (lpReceiveFunc != null)
                {
                    lpReceiveFunc(nRecLen);
                }
                Array.Copy(szTempBuf, nOffset, szFileData, nRecTotal, nRecLen);
                nRecTotal += nRecLen;
            }
            else
            {
                break;
            }
        }
        http.Close();
        return(nRecTotal == nDownSize);
    }
Ejemplo n.º 4
0
        static void Main(String[] args)
        {
            var h = new CHttp(4, DownloadChangedCallback, DownloadCompletedCallback);

            //h.Push(new SInObj("http://madplanet-patch.s3.ca-central-1.amazonaws.com", "/ServerInfo.txt"));
            h.Push(new SInObj("http://madplanet-patch.s3.ca-central-1.amazonaws.com", "/data/test2.msi"));

            while (true)
            {
                h.Proc();
                Thread.Sleep(1);
            }
        }
Ejemplo n.º 5
0
 public CClient(
     string FileName_, string ServerName_, bool VersionPath_, string DataPath_,
     TLinkFunc LinkFunc_, TLinkFailFunc LinkFailFunc_, TUnLinkFunc UnLinkFunc_,
     TDownloadChangedFunc DownloadChangedFunc_, TDownloadCompletedFunc DownloadCompletedFunc_) :
     base(FileName_, DataPath_)
 {
     _Http                  = new CHttp(1, _DownloadChanged, _DownloadCompleted);
     _ServerName            = ServerName_;
     _VersionPath           = VersionPath_;
     _LinkFunc              = LinkFunc_;
     _DownloadChangedFunc   = DownloadChangedFunc_;
     _DownloadCompletedFunc = DownloadCompletedFunc_;
     _NetB                  = new balance.CClient(_LinkS, LinkFailFunc_, UnLinkFunc_, _RecvS);
 }
Ejemplo n.º 6
0
    void DownThread()
    {
        DownResInfo resInfo = null;
        CHttp       http    = new CHttp();

        while (!m_bNeedStop)
        {
            if (PopDownFileInfo(out resInfo))
            {
                DownFile(http, resInfo.url, resInfo.nFileSize, resInfo.nDownSize);
            }
            else
            {
                break;
            }
        }
        http.Close();
        // 线程退出,线程数减一
        System.Threading.Interlocked.Decrement(ref m_nDownThreadNumb);
    }
Ejemplo n.º 7
0
    void DownFile(CHttp http, string url, int nFileSize, int nLastDownSize)
    {
        // 如果文件比较小的话,可以不分片下载,真正下载整个文件
        if (nFileSize == 0)
        {
            CHttpDown.GetDownFileSize(url, out nFileSize);
        }

        DownResFile resInfo = new DownResFile();

        resInfo.url       = url;
        resInfo.nFileSize = 0;

        if (0 == nFileSize)
        {
            // 无法获取文件大小信息,整个下载吧
            bool bSuc = DownPart(http, url, 0, 0, nFileSize, resInfo);
            NotifyDownEvent(url, bSuc, resInfo);
            return;
        }
        int nPageSize   = 1024 * 300;    // 分片的大小,应小于你的最大限制下载速度, 这里默认选用300K,读者自己根据项目修改
        int nFileOffset = nLastDownSize; // 从上一次下载的位置接着下载
        int nDownSize   = 0;

        for (; nFileOffset < nFileSize; nFileOffset += nPageSize)
        {
            // 先限速
            LimitSpeed();
            // 开始分片下载
            nDownSize = nFileOffset + nPageSize < nFileSize ? nPageSize : (nFileSize - nFileOffset);
            if (!DownPart(http, url, nFileOffset, nDownSize, nFileSize, resInfo))
            {
                NotifyDownEvent(url, false, resInfo);
                return;
            }
        }
        NotifyDownEvent(url, true, resInfo);
    }
Ejemplo n.º 8
0
    // 功能:下载文件,并将下载的文件保存到本地
    // 参数:url - 网络URL的地址
    //       szLocalPathName - 本地保存地址
    // 说明:这个接口是阻塞模式的,请不要在主线程调用
    static public bool DownFile(string url, string szLocalPathName, int nNeedDownOffset, int nNeedDownSize, long nRandSeed = 0, LPOnReceiveDownFile lpReceiveFunc = null)
    {
        CHttp  http = new CHttp(nRandSeed);
        string szServerIP = string.Empty, szObj = string.Empty;
        int    nPort = 80;

        http.ParseURL(url, ref szServerIP, ref szObj, ref nPort);

        string szAnswer = string.Empty;

        if (!http.QueryFile(ref szAnswer, szServerIP, nPort, szObj, nNeedDownOffset, nNeedDownSize, nNeedDownSize <= 0))
        {
            http.Close();
            return(false);
        }
        int nDownSize = 0, nFileSize = 0;

        if (!http.AnlyseFileLengthFromAnswer(szAnswer, ref nDownSize, ref nFileSize))
        {
            http.Close();
            return(false);
        }
        if (nNeedDownSize <= 0)
        {
            nDownSize = nFileSize;  // 这是全部下载
        }
        // 打开本地文件
        if (File.Exists(szLocalPathName))
        {
            File.Delete(szLocalPathName);
        }
        FileStream pFile = new FileStream(szLocalPathName, FileMode.CreateNew, FileAccess.Write);

        // 开始下载吧
        byte[] szTempBuf = null;

        int nRecTotal = 0;
        int nRecLen   = 0;
        int nOffset   = 0;

        while (nRecTotal < nDownSize)
        {
            nRecLen = http.FastReceiveMax(ref szTempBuf, ref nOffset);
            // 写入文件吧
            if (nRecLen > 0)
            {
                if (lpReceiveFunc != null)
                {
                    lpReceiveFunc(nRecLen);
                }
                nRecTotal += nRecLen;
                pFile.Write(szTempBuf, nOffset, nRecLen);
            }
            else
            {
                break;
            }
        }
        http.Close();
        pFile.Close();
        return(nRecTotal == nDownSize);
    }
Ejemplo n.º 9
0
    static bool     GetInetURL(string pcsURL, ref string szOutURL)
    {
        // 提取服务器的网址
        string szURL = pcsURL;

        if (szURL.IndexOf("http://", 0) != 0)
        {
            szURL = "http://" + szURL;
        }
        string szSerIP = GetMiddle(szURL, "http://", "/");

        string szObj  = string.Empty;
        int    nIndex = szURL.IndexOf('/', 6 + szSerIP.Length);

        if (nIndex != -1)
        {
            szObj = szURL.Substring(nIndex); // 必须有'/'
        }
        else
        {
            return(false);
        }

        int nServerPort = 80;

        nIndex = szSerIP.IndexOf(':', 0);
        if (nIndex != -1)
        {
            nServerPort = DistillNumb(szSerIP, nIndex + 1);
            szSerIP     = szSerIP.Substring(0, nIndex);
        }

        // 连接服务器
        CHttp tcpURL = new CHttp();

        if (!tcpURL.ClientOpen(szSerIP, nServerPort))
        {
            return(false);          // 无法连接服务器
        }

        // 格式化消息头
        StringBuilder szBuilder = new StringBuilder(512);

        ///第1行:方法,请求的路径,版本
        szBuilder.AppendFormat("GET {0} HTTP/1.1\r\n", szObj);
        ///第2行:主机
        szBuilder.AppendFormat("Host:{0}\r\n", szSerIP);
        ///第3行: 引用网址
        //szMsg.AppendFormat( "Referer:%s\r\n", szObj );

        ///第4行:接收的数据类型
        szBuilder.Append("Accept:*/*\r\n");
        ///第5行:浏览器类型
        szBuilder.Append("User-Agent:Mozilla/6.0 (compatible; MSIE 6.00; Android)\r\n");
        ///第6行:连接设置,保持
        //szMsg.AppendFormat( "Connection:Keep-Alive\r\n" );
        szBuilder.Append("Connection:close\r\n");
        szBuilder.Append("Range: bytes=0-0\r\n");
        szBuilder.Append("\r\n");

        string szMsg = szBuilder.ToString();

        tcpURL.SendToServer(szMsg);
        byte   [] chBuf         = new byte[1];
        char   [] szTotalRecBuf = new char[1024]; // 应该不会这么长吧
        int       nTotalRecLen  = 0;
        int       nStart        = 0;

        while (true)
        {
            int nRecLen = tcpURL.ReceiveChar(chBuf, 1024);
            if (nRecLen <= 0)
            {
                break;
            }
            if (nTotalRecLen + nRecLen > szTotalRecBuf.Length)
            {
                char  [] szNewBuf = new char[nTotalRecLen * 2];
                Array.Copy(szTotalRecBuf, 0, szNewBuf, 0, nTotalRecLen);
                szTotalRecBuf = szNewBuf;
            }
            szTotalRecBuf[nTotalRecLen++] = (char)chBuf[0];
            nTotalRecLen += 1;

            if (FindHttpMsgEndFlags(szTotalRecBuf, nTotalRecLen, ref nStart))
            {
                break;
            }
        }
        tcpURL.Close();

        szTotalRecBuf[nTotalRecLen] = '\0';
        string szAnswer = new string(szTotalRecBuf, 0, nTotalRecLen);

        // 分析
        szOutURL = GetMiddle(szAnswer, "Location:", "\r\n");
        szOutURL = szOutURL.Trim();
        tcpURL.Close();
        return(szOutURL.Length > 0);
    }