Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET套接字与C++;高性能插座 我的问题是要和我的同事们就C++与C语言进行一个争论。< /P>_C#_Sockets_Io Completion Ports - Fatal编程技术网

C# .NET套接字与C++;高性能插座 我的问题是要和我的同事们就C++与C语言进行一个争论。< /P>

C# .NET套接字与C++;高性能插座 我的问题是要和我的同事们就C++与C语言进行一个争论。< /P>,c#,sockets,io-completion-ports,C#,Sockets,Io Completion Ports,我们已经实现了一个接收大量UDP流的服务器。该服务器是在C++中使用异步套接字开发的,使用完成端口重叠I/O。我们使用5个完成端口和5个线程。该服务器可以轻松处理千兆网络上的500 Mbps吞吐量,而不会出现任何数据包丢失/错误(我们的测试没有超过500 Mbps) 我们曾尝试在C#中重新实现同一类型的服务器,但未能达到相同的传入吞吐量。我们使用异步接收,使用ReceiveAsync方法和SocketAsyncEventArgs池来避免为每个接收调用创建新对象的开销。每个SAEventArgs都

我们已经实现了一个接收大量UDP流的服务器。该服务器是在C++中使用异步套接字开发的,使用完成端口重叠I/O。我们使用5个完成端口和5个线程。该服务器可以轻松处理千兆网络上的500 Mbps吞吐量,而不会出现任何数据包丢失/错误(我们的测试没有超过500 Mbps)

我们曾尝试在C#中重新实现同一类型的服务器,但未能达到相同的传入吞吐量。我们使用异步接收,使用
ReceiveAsync
方法和
SocketAsyncEventArgs
池来避免为每个接收调用创建新对象的开销。每个
SAEventArgs
都有一个缓冲区,因此我们不需要为每个接收分配内存。该池非常非常大,因此我们可以将100多个接收请求排队。此服务器无法处理超过240 Mbps的传入吞吐量。超过这个限制,我们会在UDP流中丢失一些数据包

我的问题是:我是否期望使用C++套接字和C?我的观点是,如果在.NET中正确管理内存,那么性能应该是相同的

附带问题:有谁知道一篇好文章/参考资料来解释.NET套接字如何在引擎盖下使用I/O完成端口吗

有谁知道一篇好文章/参考资料来解释.NET套接字如何在引擎盖下使用I/O完成端口吗

我怀疑唯一的参考是实现(即Reflector或其他汇编反编译器)。这样,您会发现所有异步IO都通过一个IO完成端口,回调在IO线程池(独立于普通线程池)中处理

使用5个完成端口

我希望使用一个完成端口将所有IO处理到一个线程池中,每个线程池一个线程为完成提供服务(假设您正在异步执行任何其他IO,包括磁盘)

如果您有某种形式的优先级安排,多个完成端口是有意义的

我的问题是:我应该期待使用C++套接字和C? 是或否,取决于“使用…套接字”部分的定义范围。就从异步操作开始到完成被发布到完成端口的操作而言,我认为没有明显的区别(所有处理都在Win32 API或Windows内核中)

但是.NET运行时提供的安全性会增加一些开销。例如,将检查缓冲区长度,验证代理等。如果应用程序的限制是CPU,那么这很可能会产生差异,并且在极端情况下,一个小的差异很容易累积起来

此外,.NET版本偶尔会暂停GC(.NET 4.5执行异步收集,因此将来会更好)。有一些技术可以最大限度地减少垃圾积累(例如,重用对象而不是创建对象,在避免装箱的同时利用结构)


<>最后,如果C++版本工作并满足你的性能需求,为什么Po.E/P>< P>我猜你没有看到同样的性能,因为.NET和C++实际上在做不同的事情。您的C++代码可能不安全,或者检查边界。此外,您是否只是在测量无需任何处理即可接收数据包的能力?或者您的吞吐量是否包括数据包处理时间?如果是这样,那么您为处理数据包而编写的代码可能没有那么高效


我建议使用分析器来检查花费的时间最多的地方,并尝试对其进行优化。实际的套接字代码应该是相当好的。

< P>不能从C++到C语言的代码端口直接执行,并且期望相同的性能。NET在内存管理(GC)方面做的比C++更大,并且确保代码是安全的(边界检查等)。 我会为所有IO操作分配一个大的缓冲区(例如65535x500=32767500字节),然后为每个
SocketAsyncEventArgs
(以及发送操作)分配一个块。内存比CPU便宜。使用缓冲区管理器/工厂为所有连接和IO操作提供块(Flyweight模式)。微软在他们的异步示例中就是这样做的


Begin/End和Async方法都在后台使用IO完成端口。后者不需要为提升性能的每个操作分配对象。

+ 1非常好地询问了C++可能的重复没有插槽。您是在谈论Posix套接字还是其他网络库?@RTS,JohnSaunders:为什么对套接字类型的细节吹毛求疵?每个人都能理解这是win32 sockets和.NET sockets,因为他谈到了C#和IO完成端口。@jgauffin:precision是件好事+1根据Telerik JustDecompile,
SocketAsyncEventArgs
使用
System.Threading.Overlapped
,它的实现告诉了几乎所有关于iocompletion端口是如何使用的。感谢您的详细回答。我已经看过了使用reflector的套接字代码,.NET套接字在执行异步操作时使用IO完成端口。这使我更困惑,因为我期望类似的性能作为我的非托管代码,因为它们都依赖于相同的技术……在C++中,我使用5完成端口,因为我有一个线程池5个线程等待这些端口(1线程每ICONCOMPART)。当数据到达端口时,线程“唤醒”,读取数据,将其发布到另一个工作线程上,然后在端口上再次侦听数据。在C#中,我们将服务器剥离到最低限度,只是为了验证我们是否可以接收到t