首页 新闻 会员 周边 捐助

.net Socket通信效率

0
悬赏园豆:20 [已解决问题] 解决于 2010-09-24 14:39

问题描述:

     现在准备用C#开发一台数据接收服务器(高速、海量的数据、对实时性要求高且不能丢包,数据包格式为定义好的结构体)。数据源(发送数据的服务器)服务器端程序由C/C++开发。数据接收服务器与数据源服务器之间用TCP Socket通信。

      接收数据时有两种方式,第一种是把接收到的C++结构体,转换为C#对应的结构体形式,网上有转换参考代码,这里不详细说。第二种是读取数据包的字节,然后转换为相应的数据类型,比如,在C++语言结构体中第一个字段为int型(占四个字节),在C#中转换时,从接收到的结构体字节数组中读取4个字节,然后强制类型转换为int型,以前做股票程序时,这种方式我用过,确实可行。

     提问:以前两种用C#接收数据的方式哪一种效率更高(即对CPU的性能损失较少;不会导致数据接收缓冲区内积累大量的数据来不及处理而发生丢包现象),或都哪位朋友有更好的建议?我的看法是两种速度差不多,因为都是在内存进行处理的,不过接下来几天我会拿两者做压力测试,自己求证一下。但我是希望高手给我分析一下,不胜感激。

    再提问:有没有办法控制TCP连接中,数据接收缓冲区的大小?

     期望高手的回答。

       

 

 

X教授的主页 X教授 | 菜鸟二级 | 园豆:240
提问于:2010-09-21 16:04
< >
分享
最佳答案
0

第一种要高,因为机器硬件目前一般都是32位或者64位的,批量拷贝肯定比一个字节一个字节的拷贝和转换要快很多。

C# 中 数据接收缓冲区是通过 ReceiveBufferSize 来调整的,你用 C/C++ 不知道你是通过什么方式来做,是直接调用 socket 的  windows api 呢,还是用 C++ 封装好的类,所以暂时无法回答你第二个问题。

收获园豆:20
eaglet | 专家六级 |园豆:17139 | 2010-09-22 07:44
“第一种要高,因为机器硬件目前一般都是32位或者64位的,批量拷贝肯定比一个字节一个字节的拷贝和转换要快很多。”这一点我觉得有点含糊,现在收到的结构体中,大部分4字节或8字节数据,还有部分6字节的数据。假设现在收到的数据包结构体是18个字节(第一个字段为Byte[]数组6字节,第二个为Int型4字节,第三个为Float型8字节),比如我现在的机器32位器,如果是整体拷贝,每次处理4个字节的数据,也要5次处理完毕,相当于用了5个指令周期。如果读取相应字节数,然后转换的方法做,比如,binr.ReadByte6(6)(读取6个字节),binr.ReadUInt()(读取四个字节),binr.ReadSingle()(读取8个字节),如果这种做效率是否损失太多。
X教授 | 园豆:240 (菜鸟二级) | 2010-09-23 11:33
还有一点然望大哥指教,关于C/C++通信中,直接调用Socket的Windows api与C++封装好的类有什么区别,C++封装好的类是否不是用的winsocket。顺便还想请教一下,我也是昨天了解到的,数据源服务器操作系统是用的Soloris,是用C语言写的服务器端,它的Socket是否有另外的一套机制。
X教授 | 园豆:240 (菜鸟二级) | 2010-09-23 11:38
单纯从指令上说,18个字节,按字节读,需要至少18个指令周期,其实不只18个,因为需要先拷贝到寄存器,然后从寄存器再从寄存器拷贝到内存。而批量拷贝,硬件上是有批拷贝指令的,那是很快的。不信的话,你可以用 Array.Copy 与 foreach 这样按byte 拷贝两者做个比较,前者要快很多。另外你按字节过来后还要做转换,而不是直接拷贝到目标内存,这个又是一个耗时的操作,还有你调用那几个函数,每调用一次都要压栈,出栈,这个也耗时。 Windows 下 MFC 封装了Socket 的访问类,底层当然也是调用winsocket 如果是 Soloris ,肯定不是 winsocket ,调用的API肯定不一样,但机制是一样的,因为TCP IP 的协议栈是规定死的。
eaglet | 园豆:17139 (专家六级) | 2010-09-23 13:06
受教了,呵呵!现在终于明白了,大哥的基础比我扎实多了,可不可把你的联系方式(QQ、MSN、邮箱均可)告诉我。谢谢!
X教授 | 园豆:240 (菜鸟二级) | 2010-09-23 14:50
对了,关于第二个问题,我还想请教一下,如果数据提供方是Soloris系统,连接建立后(是数据源服务器主动数据接收方,然后发送数据),我现在调整接收缓冲区ReceiveBufferSize 的大小(默认大小8192,即4KB数据),它和TCP协议中流量控制参数WSS有关系吗?我自己有一个想当然的认为,我认为调整接收缓冲区就是改变了TCP协议滑动窗口的大小,不知是否正确。
X教授 | 园豆:240 (菜鸟二级) | 2010-09-23 15:05
@X教授: ReceiveBufferSize 和 滑动窗口的大小不是一回事,ReceiveBufferSize 应该是提供给接口调用用的,不是TCP协议里面的参数。联系方式发站内短信给你了。
eaglet | 园豆:17139 (专家六级) | 2010-09-24 07:54
谢谢!
X教授 | 园豆:240 (菜鸟二级) | 2010-09-24 14:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册