我要用C#做一个数据采集系统的上位机,TCP连接,但现在的问题是下位机传的太快,每秒10万数据,一个数据4字节,我看了下我的上位机一分钟才接4000数据,还丢数

白日梦想家-翡翡翡 2017-11-02 11:44:12
我要用C#做一个数据采集系统的上位机,TCP连接,但现在的问题是下位机传的太快,每秒10万数据,一个数据4字节,我看了下我的上位机一分钟才接4000数据,还丢数。
所以,我想问一下,有什么方法能够提高上位机的接收速度和保证接收数据完整
下位机传来四个字节代表一个数据,前三个字节是要处理的数据,最后一个字节是板号及通道号
我现在已经把数据采集和处理分到两个线程中了,但速度没有丝毫提升,丢数问题没有解决
/// <summary>
/// 下位机信息接收方法
/// </summary>
/// <param name="obj"></param>
private void reciveMsg(object obj)
{
Socket client = obj as Socket;
while (true)
{
byte[] FourB = new byte[4];
try
{
byte[] buffer = new byte[BytesCounts];
int length = client.Receive(buffer);
if(length !=0)
lenQueue.Enqueue(length);
myqueue.Enqueue(buffer);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
IPEndPoint point = client.RemoteEndPoint as IPEndPoint;
label2.Text = (point.ToString() + "断开连接。。。");
break;
}

}

}

/// <summary>
/// 下位机信息处理方法
/// </summary>
/// <param name="obj"></param>
private void DataProcessing(object obj)
{
Socket client = obj as Socket;
while (true)
{
byte[] FourB = new byte[4];
try
{
byte[] bufferOut = new byte[BytesCounts];
if (myqueue.Count != 0)
{
bufferOut = myqueue.Dequeue() as byte[];
int myLength = Convert.ToInt16(lenQueue.Dequeue());
string res = Encoding.UTF8.GetString(bufferOut, 0, bufferOut.Length);
for (int i = 0; i <= myLength- 4; i = i + 4)
{
if ((bufferOut[i] & 0x80) != 0x80) //判断是否是负数,如果是负数else处理
{
FourB[3] = 0x00;
FourB[2] = bufferOut[i];
FourB[1] = bufferOut[i + 1];
FourB[0] = bufferOut[i + 2];
}
else
{
FourB[3] = 0xff;
FourB[2] = bufferOut[i];
FourB[1] = bufferOut[i + 1];
FourB[0] = bufferOut[i + 2];
}

//得到的4字节数据处理为要显示的数据
int temp = BitConverter.ToInt32(FourB, 0);
double temp2 = Convert.ToDouble(temp);
double SCdata = (temp2 / 8388608) * 12.5;


//板号判断,通道号判断存入
switch (bufferOut[i + 3] & 0x38)
{
case (0x08):
{
int tongdaoName = bufferOut[i + 3] & 0x07;
if (tongdaoName != 0)
{
double[] tempArr = new double[3] { SCdata, 1, tongdaoName };
tempQueue.Enqueue(tempArr);
}
break;
}
case (0x10):
{
int tongdaoName = bufferOut[i + 3] & 0x07;
if (tongdaoName != 0)
{
double[] tempArr = new double[3] { SCdata, 2, tongdaoName };
tempQueue.Enqueue(tempArr);
}
break;
}
case (0x18):
{
int tongdaoName = bufferOut[i + 3] & 0x07;
if (tongdaoName != 0)
{
double[] tempArr = new double[3] { SCdata, 3, tongdaoName };
tempQueue.Enqueue(tempArr);
}
break;
}
case (0x20):
{
int tongdaoName = bufferOut[i + 3] & 0x07;
if (tongdaoName != 0)
{
double[] tempArr = new double[3] { SCdata, 4, tongdaoName };
tempQueue.Enqueue(tempArr);
}
break;

}
}
//Array.Clear(buffer, 0, buffer.Length);
label2.Text = ("接收到的消息:" + res);
}
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
IPEndPoint point = client.RemoteEndPoint as IPEndPoint;
label2.Text = (point.ToString() + "断开连接。。。");
break;
}

}

}
...全文
885 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
搞了马上就两周了,没有进展,,,有没有人教教我,,,,
  • 打赏
  • 举报
回复
大佬们!!!!!!求指教啊
  • 打赏
  • 举报
回复
引用 13 楼 guanyinsishengzi 的回复:
C# IOCP 一篇老文章 里面有服务端Demo和源码 http://www.cnblogs.com/zjoch/p/4175291.html
谢谢!
  • 打赏
  • 举报
回复
我没写逻辑吧,只是接收数据,存队列
guanyinsishengzi 2017-11-02
  • 打赏
  • 举报
回复
C# IOCP 一篇老文章 里面有服务端Demo和源码 http://www.cnblogs.com/zjoch/p/4175291.html
  • 打赏
  • 举报
回复
引用 9 楼 gangAndgang的回复:
BytesCounts 设置为32K, 一次性最多读32K字节, 用beginrecive类似的方式来异步读, 然后把接收到的长度和数据放入队列, 另一个线程再去分析这个队列,4个字节4个字节的读,读出来,再发到处理线程中去,这样性能应该能提升 记得以前copy文件,这个缓冲区大小对性能影响非常大
我现在用4k的bytescount,之前扩到8k就出现没有可分配的内存的问题了,而且我现在已经是数据采集一个线程,处理一个线程了
绿领巾童鞋 2017-11-02
  • 打赏
  • 举报
回复
哥们 ,接收部分 ,别写 逻辑 ,先保存在 临时变量 ,数据解析 额外 线程去做,如果 在接收 部分 写 解析业务 ,当然 延迟 会大
xian_wwq 2017-11-02
  • 打赏
  • 举报
回复
1. 每秒10万点,每笔数据4字节,也就400k/s,所以这个数据量对普通的百兆网无压力。 2.在windows平台,要提高性能,还得iocp,用c#,就得用SocketAsyncEventArgs 异步通讯开发比较麻烦,但是性能远超同步模式的send,receive 3.要提高速度,用单个线程来解析效率太低 因为数据直接并没有业务上的关联,所以可以实现并发解析 c#提供了线程池或者任务机制,可以直接用 lz代码的问题 1.如果多个线程操作queue,必须要处理同步,否则就是各种奇怪的数据 2.使用TCP不处理“粘包”,代码基本不可用
gangAndgang 2017-11-02
  • 打赏
  • 举报
回复
BytesCounts 设置为32K, 一次性最多读32K字节, 用beginrecive类似的方式来异步读, 然后把接收到的长度和数据放入队列, 另一个线程再去分析这个队列,4个字节4个字节的读,读出来,再发到处理线程中去,这样性能应该能提升 记得以前copy文件,这个缓冲区大小对性能影响非常大
sdfgrtyu 2017-11-02
  • 打赏
  • 举报
回复
每秒10万数据速度也太快了,能接收过来吗,?
  • 打赏
  • 举报
回复
引用 4 楼 u012948520 的回复:
每秒10万条4B的数据,也就是400KB/s,小的很。 BytesCounts你设置的多少?设个1024*2不过分吧?
我设的4096,但就是不行,我没秒才处理不到4000*7的数据,四字节的,也就才28KB/S 我程序里边开了四个还是五个线程,要一直运行的有三个,分别是数据采集,处理,和实时显示,我在想线程太多会不会把速度拉下来? 而且现在一直有丢数的问题,,,感觉应该就是BUFFER被存满了导致的,不知道该怎么解决 对,我各个线程没用INVOKE的操作,就是线程一直都是开着的,会有影响吗
by_封爱 版主 2017-11-02
  • 打赏
  • 举报
回复
异步就行了 网上找点例子 那种while(true)基本都是"玩"的...不能实际应用
  • 打赏
  • 举报
回复
引用 3 楼 chuheiqian 的回复:
用异步接收数据BeginReceive,在完成回调事件里面去添加队列操作
能行吗,这样的话是不是得接收数据,然后调用处理数据的方法,数据处理完了在回到接收数据的线程,那这段时间太长了,BUFFER那个区间迟早是要被存满的啊,是不是这样,,,
白衣如花 2017-11-02
  • 打赏
  • 举报
回复
每秒10万条4B的数据,也就是400KB/s,小的很。 BytesCounts你设置的多少?设个1024*2不过分吧?
倒退一天 2017-11-02
  • 打赏
  • 举报
回复
用异步接收数据BeginReceive,在完成回调事件里面去添加队列操作

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧