我参考一个获取图片的C#代码,改写成了vc代码,都是用XMLHTTPRequest设置用户名密码,在HTTP服务器获取图片数据,vc程序里有时候能够取得图片有时却得不到,图片的长度为0,而C#代码却没有问题!!不知何故
分别贴出C++和C#代码.....
  再介绍下大体情况,我在编写一个事件服务,在两个端口监听,一个是监听事件,一个是监听客户端连接然后往客户端发送事件的,监听到事件后获取事件相关XML,然后解析从中获取图片地址,然后用XMLHTTPRequest取得图片数据,解析xml并获取图片在一个线程内运行,有连续事件时会有多个线程同时运行。不知是否多线程造成了图片获取出错

解决方案 »

  1.   


    public byte[] GetAlertSnapshot(string snapshotUrl )
    {
        try
        {
            string URI = getDeviceURI( this.txtDevice.Text);
            URI += getResourceURL(snapshotUrl);
            // setting parameters
            HttpWebRequest request = WebRequest.Create(URI) as HttpWebRequest;
            request.Method = "GET";
            request.KeepAlive = true;
            request.Timeout = ClsParams.HttpRespTimeOut;
            System.Net.Cookie cookie = connCookie;
            CookieContainer cookieCon = new CookieContainer();
            cookieCon.Add(request.RequestUri, cookie);
            request.CookieContainer = cookieCon;        // receive data  
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            System.IO.Stream responseStream = response.GetResponseStream();
            string contLenStr = response.Headers["Content-Length"].ToString();
            int contLen = System.Convert.ToInt32(contLenStr);
            byte[] data = new byte[contLen];        int recvLen = 0;
            do
            {
                int wantToRead = contLen - recvLen;
                recvLen += responseStream.Read(data, recvLen, wantToRead);
            } while (recvLen > 0 && recvLen < contLen);
            responseStream.Close();
            if (recvLen > 0)
            {
                byte[] picData = new byte[recvLen];
                Array.Copy(data, 0, picData, 0, recvLen);
                return picData;
            }
            return null;
        }
        catch (Exception ex)
        {
        }
    }
    这是c#代码,这个没问题
      

  2.   


    void GetAlertSnapshot( char * snaphot,AlertDetail * alertDetail,int snapShotIndex)
    {
        //组装图片url
        CString deviceAddr;
        deviceAddr.Format("http://%s:%d",ip,port);
        deviceAddr.Append(snaphot);
        MSXML2::IXMLHTTPRequestPtr m_spXMLHTTPRequest;
        m_spXMLHTTPRequest = NULL;
        m_spXMLHTTPRequest.CreateInstance(L"Msxml2.XMLHTTP.4.0");
        if (NULL != m_spXMLHTTPRequest)
        {
            m_spXMLHTTPRequest->open("GET", deviceAddr.AllocSysString(), VARIANT_FALSE,userName,passWord);
            m_spXMLHTTPRequest->send();
            //取得图片长度
            _bstr_t responseHeader("Content-Length") ;
            _bstr_t Contentlength =m_spXMLHTTPRequest->getResponseHeader(responseHeader);
            //取得图片数据
            _variant_t dataVar= m_spXMLHTTPRequest->GetresponseBody();
            if (strncmp("TripwireEventSynopsis",alertDetail->eventType,strlen("TripwireEventSynopsis"))==0)
            {
                if ((LPCTSTR)Contentlength!=NULL)
                {
                    int length = atoi(Contentlength);
                    alertDetail->snapshots.snapshots[snapShotIndex].snapshotData =dataVar;
                    alertDetail->snapshots.snapshots[snapShotIndex].snapshotSize=length;
                }
                else
                {
                    COleSafeArray safearray;
                    LONG len;    
                    //VARIANT型变量转换为ColeSafeArray型变量 
                    safearray=dataVar; 
                    //得到有效数据长度 
                    len=safearray.GetOneDimSize();
                    if (0 == len)
                    {
                        ::MessageBox(NULL,"图片长度为0","",0);
                    }
                }
            }
        }
    }
    这是c++代码,这个有问题
      

  3.   

    XMLHTTP默认是异步的,我没看见你设置成同步模式
      

  4.   

    m_spXMLHTTPRequest->open("GET", deviceAddr.AllocSysString(), VARIANT_FALSE,userName,passWord);
    VARIANT_FALSE就说明是同步的,再说这里同步异步会影响结果吗 
      

  5.   

    还有个问题,vc下我不能想c#那样调用GetResponseStream,当初试过,根本没有得到流,我想应该是有方法的,要不然vc下设置这个方法真的是无益  。谁会?
      

  6.   

    GetResponseStream是HttpWebRequest对象的吧?我记得XMLHTTP没有这个?在失败的时候只说失败是很难找到答案的。你至少得做一些事情让出错原因更明朗一点,例如:服务器到底给没给你回复?如果有,那么回复内容是什么?如果没有,你遇到得异常是什么。另外一个很好得诊断手法是用抓包软件看http报文内容。不要指望别人看两行代码就知道你错在哪了,有时候即使是完全对得代码都可能失败,代码得正确与否不是程序能否工作得唯一决定因素
      

  7.   

    GetResponseStream是XMLHTTP的方法,得到一个_variant_t,类型为VT_UNKNOWN,我不知道这怎么用....
      

  8.   

    MSDN有很多有用得知识,如果你不熟悉什么,查询MSDN是很重要得。VARIANT会介绍VT_UNKNWON是啥意思(见下面),我估计这是一个实现了IStream的接口,因此你可以QueryInterface找到接口,然后读。我估计这种东西用C#,VB更容易访问,如果你要用C++,先去学COM吧VT_UNKNOWN A pointer to an object that implements the IUnknown interface is passed in punkVal. 
    VT_UNKNOWN | VT_BYREF A pointer to the IUnknown interface is passed in ppunkVal. The pointer to the interface is stored in the location referred to by ppunkVal. 
      

  9.   

    我得到了IStream接口了,可以取得数据,但是有时候还是取不到。再说一下,HTTP服务端我估计是用C#做的,因为我用的他们系统的SDK也是用C#开发,猜测如果是的话,会不会语言不通也会有影响?