C# 通過Socket讀取大量數據的示例
在C#中經常會用到Socket去接收和發(fā)送數據,而且也是非常方便的,有時候我們會向服務端去請求數據,如果返回的數據量很大,比如超過10M甚至是更多,那么該怎樣去接收數據呢?下面以一個在項目中用到的實例去分析和解釋這個問題,先看看下面的這段代碼?
/// <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("總共花費時間:"+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的這個同步方法來進行接收,datas是我們接收數據的Byte數組,recvsize是當前接收的字節(jié)起點(offset),dataSize-recvsize是接收的緩沖區(qū)大小,在這個While循環(huán)里面,只要是recvsize < dataSize就會不停的去接收數據,當然如果數據量很大的話總有一個時刻recvsize >= dataSize,這個時候我怎就需要增加dataSize了,這里我們去動態(tài)增加1KB的大小,通過這樣一個邊界控制我們就能夠去準確獲取所有的數據了......
當然這種方式接收數據的缺點就是通過同步的方式,如果接收的數據太多的話,那么花費的時間可能就過長了,特別是在更新UI界面的時候,需要采用異步非阻塞的Socket來接收數據了,或者單獨來開一個線程來進行數據接收,然后通過Application.Current.Dispatcher.BeginInvoke的方式來更新到UI上面,不然界面就會卡死,這個需要我們去認真分析......
另外一個當我們這樣接收數據然后存入XML文件時,可能XML數據都是連在一起并不能主動換行,這個可以通過下面的方式來解決。
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數據后,通過XmlTextWriter寫入到XML文件中時,需要設置縮進格式:xtw.Formatting = Formatting.Indented;這樣寫入數據時數據就會完整,并且處于對齊方式。
以上就是C# 通過Socket讀取大量數據的示例的詳細內容,更多關于C# 通過Socket讀取數據的資料請關注腳本之家其它相關文章!

