溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何在C#中使用Socket讀取超大的數(shù)據(jù)

發(fā)布時間:2021-03-01 16:35:09 來源:億速云 閱讀:225 作者:Leah 欄目:開發(fā)技術(shù)

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)如何在C#中使用Socket讀取超大的數(shù)據(jù),文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

/// <summary>
        /// 返回攝像頭信息
        /// </summary>
        private void RcvCameraInfos(object obj)
        {
            string sourceIp = System.Configuration.ConfigurationSettings.AppSettings["SourceIP"].ToString();
            string sourcePort = System.Configuration.ConfigurationSettings.AppSettings["SourcePort"].ToString();
 
            Socket mysocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(sourceIp), int.Parse(sourcePort));
            mysocket.Connect(ipEndPoint);
 
            DateTime start = DateTime.Now;
 
            string s = "<?xml version=\"1.0\" ?>";
            s += "<info  name=\"getcameracodematrixtable\"/>\0";
            byte[] buffer = System.Text.ASCIIEncoding.GetEncoding("GB2312").GetBytes(s);
            mysocket.Send(buffer);
 
            Action<string> OnCamraInfoRcvCompleted = obj as Action<string>;
             
            int recvsize = 0;
            int dataSize = 2048 * 1000;
            int ret = 0;
            byte[] datas = new byte[dataSize];
            SortedList<string, string[]> cameraDictionnary = new SortedList<string, string[]>();
            string xmlString = "";
            while (recvsize < dataSize)
            {
                ret = mysocket.Receive(datas, recvsize, dataSize - recvsize, SocketFlags.None);
                if (ret <= 0)
                {                   
                    break;
                }                  
                recvsize += ret;
                if (datas[recvsize - 1] == 0)
                {                   
                    break;
                }
                if (recvsize >= dataSize)
                {
                    byte[] buff2 = new byte[dataSize + 1024];
                    datas.CopyTo(buff2,0);
                    datas = buff2;
                    dataSize += 1024;               
                }
            }
            xmlString = System.Text.ASCIIEncoding.GetEncoding("GB2312").GetString(datas, 0, recvsize - 1);
            DateTime end = DateTime.Now;
            TimeSpan span = end - start;
            System.Windows.MessageBox.Show("總共花費(fèi)時間:"+span.TotalSeconds.ToString()+"秒");
            this._videoSourceXmlString = xmlString;
            if (cameraDictionnary != null)
            {
                if (OnCamraInfoRcvCompleted != null) OnCamraInfoRcvCompleted(xmlString);
            }
        }

  上述這段代碼的核心是在While循環(huán)里面,我們首先接收的BufferSize,這里我們定義2048*1000個字節(jié)的大小,ret = mysocket.Receive(datas, recvsize, dataSize - recvsize, SocketFlags.None);通過Socket的這個同步方法來進(jìn)行接收,datas是我們接收數(shù)據(jù)的Byte數(shù)組,recvsize是當(dāng)前接收的字節(jié)起點(diǎn)(offset),dataSize-recvsize是接收的緩沖區(qū)大小,在這個While循環(huán)里面,只要是recvsize < dataSize就會不停的去接收數(shù)據(jù),當(dāng)然如果數(shù)據(jù)量很大的話總有一個時刻recvsize >= dataSize,這個時候我怎就需要增加dataSize了,這里我們?nèi)討B(tài)增加1KB的大小,通過這樣一個邊界控制我們就能夠去準(zhǔn)確獲取所有的數(shù)據(jù)了......

  當(dāng)然這種方式接收數(shù)據(jù)的缺點(diǎn)就是通過同步的方式,如果接收的數(shù)據(jù)太多的話,那么花費(fèi)的時間可能就過長了,特別是在更新UI界面的時候,需要采用異步非阻塞的Socket來接收數(shù)據(jù)了,或者單獨(dú)來開一個線程來進(jìn)行數(shù)據(jù)接收,然后通過Application.Current.Dispatcher.BeginInvoke的方式來更新到UI上面,不然界面就會卡死,這個需要我們?nèi)フJ(rèn)真分析......

  另外一個當(dāng)我們這樣接收數(shù)據(jù)然后存入XML文件時,可能XML數(shù)據(jù)都是連在一起并不能主動換行,這個可以通過下面的方式來解決。

private void SaveCurrentInfoToXML(string recevInfo)
       {
           string filePath=System.AppDomain.CurrentDomain.BaseDirectory+"CameraInfo.xml";
           XmlDocument xd = new XmlDocument();
           if (File.Exists(filePath))
           {
               xd.Load(filePath);              
           }
           else
           {
               XmlDeclaration xmlDec;
               XmlElement xmlEle;
               xmlDec = xd.CreateXmlDeclaration("1.0","UTF-8",null);
               xd.AppendChild(xmlDec);
               xmlEle = xd.CreateElement("Info");
               xd.AppendChild(xmlEle);
           }
           xd.LoadXml(recevInfo);
           XmlTextWriter xtw = new XmlTextWriter(filePath, Encoding.UTF8);
           xtw.Formatting = Formatting.Indented;
           xd.Save(xtw);
            
            
       }

  這里我們接收到XML數(shù)據(jù)后,通過XmlTextWriter寫入到XML文件中時,需要設(shè)置縮進(jìn)格式:xtw.Formatting = Formatting.Indented;這樣寫入數(shù)據(jù)時數(shù)據(jù)就會完整,并且處于對齊方式。

上述就是小編為大家分享的如何在C#中使用Socket讀取超大的數(shù)據(jù)了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI