C#通过Socket读取大量数据
在C#中经常会用到Socket去接收和发送数据,而且也是非常方便的,有时候我们会向服务端去请求数据,如果返回的数据量很大,比如超过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循环里面,我们首先接收的BufferSize,这里我们定义2048*1000个字节的大小,ret = mysocket.Receive(datas, recvsize, dataSize - recvsize, SocketFlags.None);通过Socket的这个同步方法来进行接收,datas是我们接收数据的Byte数组,recvsize是当前接收的字节起点(offset),dataSize-recvsize是接收的缓冲区大小,在这个While循环里面,只要是recvsize < dataSize就会不停的去接收数据,当然如果数据量很大的话总有一个时刻recvsize >= dataSize,这个时候我怎就需要增加dataSize了,这里我们去动态增加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读取大量数据的更多相关文章
- 云计算之路-阿里云上:原来“黑色0.1秒”发生在socket读取数据时
在昨天的博文(云计算之路-阿里云上:读取缓存时的“黑色0.1秒”)中我们犯了一个很低级的错误——把13ms算成了130ms(感谢陈硕发现这个错误!),从而对问题的原因作出了错误的推断,望大家谅解! 从 ...
- Android笔记:Socket客户端收发数据
client.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" and ...
- 2、 Spark Streaming方式从socket中获取数据进行简单单词统计
Spark 1.5.2 Spark Streaming 学习笔记和编程练习 Overview 概述 Spark Streaming is an extension of the core Spark ...
- C#读取Modbus数据
最近在做采集的一些任务所以学了一下Modbus通信,学了好几天昨天终于把大概弄明白了,其实简单来说就是客户端向设备发送一个请求报文请求数据,服务器端根据请求报文向客户端端回发一个报文,客户端在接收到响 ...
- java的poi技术读取Excel数据到MySQL
这篇blog是介绍java中的poi技术读取Excel数据,然后保存到MySQL数据中. 你也可以在 : java的poi技术读取和导入Excel了解到写入Excel的方法信息 使用JXL技术可以在 ...
- Hive读取外表数据时跳过文件行首和行尾
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 有时候用hive读取外表数据时,比如csv这种类型的,需要跳过行首或者行尾一些和数据无关的或者自 ...
- 读取数据库数据,并将数据整合成3D饼图在jsp中显示
首先我将生成饼图的方法独立写成一个PieChar.java类,详细代码如下:(数据库需要自己建,如有需要的话) import java.io.IOException; import java.sql. ...
- C# TCP socket发送大数据包时,接收端和发送端数据不一致 服务端接收Receive不完全
简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...
- .NET读取Excel数据,提示错误:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序
解决.NET读取Excel数据时,提示错误:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序的操作: 1. 检查本机是否安装Office Access,如果未安装去去h ...
随机推荐
- mysql锁2
死锁: 指两个事务或者多个事务在同一资源上相互占用,并请求对方所占用的资源,从而造成恶性循环的现象. 出现死锁的原因: 系统资源不足: 进程运行推进的顺序不当: 资源分配不当. 产生死锁的四个必要条件 ...
- 高精度除法(b为int类型)
#include<iostream> #include<cstring> #include<cstdio> using namespace std; ],a[],b ...
- 淡旺季机票的价格问题(switch语句与if-else语句嵌套)
项目背景 淡旺季机票的价格,原价机票价格为5000元, 淡季头等舱打5折,经济舱打4折 旺季头等舱打9折,经济舱打8折 要求 编写程序实现: 输入任意的月份与舱位来计算机票的价格 1代表头等舱,2代表 ...
- javaScript的原型模式
一.原型模式: 这个只存在于函数中. 我们在创建的每一个函数中都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以有特定类型 的所有实例共享的属性和方法 ...
- 深入浅出:HTTP/2
上篇文章深入浅出:5G和HTTP里给自己挖了一根深坑,说是要写一篇关于HTTP/2的文章,今天来还账了. 本文分为以下几个部分: HTTP/2的背景 HTTP/2的特点 HTTP/2的协议分析 HTT ...
- 微信小程序—如何获取用户输入文本框的值
我们就拿简单常用的登录来举例子吧,先看最终效果图片
- H5 文字属性
03-文字属性 我是文字 我是文字 abc我是段落 <!DOCTYPE html> <html lang="en"> <head> <me ...
- BZOJ1969 航线规划
给定一个无向图,每次删除一条边,求每次有多少关键边.一条边是关键边,当且仅当从1到n的所有路径都包含这条边.所有时刻图都联通. 考虑倒着做.相当于给一棵树,每次加一条边,这样树上这条边的两个端点间的路 ...
- nginx的The page you are looking for is temporarily unavailable错误解决办法
访问网站时出现如下错误,如下图: 检查php fastcgi进程数,如下图: 输出0则表示fastcgi进程数够大,修改scgi_params文件,如下图: 然后重启php-fpm和nginx,重新访 ...
- 通过设置线程池的最小线程数来提高task的效率,SetMinThreads。
http://www.cnblogs.com/Charltsing/p/taskpoolthread.html task默认对线程的调度是逐步增加的,连续多次运行并发线程,会提高占用的线程数,而等若干 ...