NetworkStream.Write vs. Socket.Send
本文关键字:Send Socket vs Write NetworkStream | 更新日期: 2023-09-27 18:00:50
我有一个使用自定义FTP库的c#应用程序。现在我使用Socket.Send来发送数据,但我想知道用Socket启动NetworkStream并使用NetworkStream.Write是否更好。
使用其中一个比使用另一个有什么好处吗?
NetworkStream
的优势主要来源于它是Stream
。Socket
的缺点是从抽象I/O源(如Stream
(读取和写入的通用代码无法处理Socket
。
NetworkStream
的主要用例是,您在其他地方有一些从Stream
读取或写入的代码,并且您希望可以将其与Socket
一起使用。你会知道如果在这种情况下,那么NetworkStream
将是一个很大的帮助!
例如,您有一个通信库,并且支持从文件、命名管道和TCP/IP序列化消息。I/O类的理想选择是Stream
。然后,序列化方法可以接受FileStream
、PipeStream
或NetworkStream
。它甚至会接受MemoryStream
。这是抽象的好处,因为在我们创建流之后,方法可以与它交互,而不知道它是什么类型的流。
从这个意义上讲,NetworkStream
使用适配器设计模式。它将Socket
API调整为Stream
API,以便期望Stream
的客户端可以使用它
最后,问题是,如果NetworkStream
是Socket
的Stream
适配器,我们应该使用哪一个?好吧,如果您需要Stream
,那么NetworkStream
是您唯一的选择。如果您不需要Stream
,那么您可以使用您最熟悉的API。如果您已经成功使用Socket
,则没有迫切的理由切换到NetworkStream
。
您可以将NetworkStream
的创建与抽象Stream
的创建分开,这样您就可以更改传输或简单地创建用于测试的Stream
存根。
由于方法本身的问题——内部的NetworkStream.Write
有唯一的操作(除了状态检查(streamSocket.Send(buffer, offset, size, SocketFlags.None);
——所以它与在套接字上调用它基本相同。
使用NetworkStream::Write
的.NET Framework实现的一个缺点是,如果底层网络(OSI层1-4(无法接收整个数据缓冲区,则您不会意识到(可能除了检查.NET Networking性能计数器。(
不可靠
类似的内容出现在Microsoft.NET Framework的NetworkStream::Write
中System.dll:
try
{
socket.Send(buffer, offset, size, SocketFlags.None);
}
/* ... catch{throw;} */
请注意,返回值(表示Send()
写入的字节数(是如何被丢弃的。这表明NetworkStream::Write
对于低于标准的网络(漫游/无线(或可能成为IO绑定(超过可用带宽(的网络来说是不可靠的
不止一个实现
您可以找到其他实现,这些实现会写入所有字节,直到所有buffer
都被写入(或发生其他故障(。这是一种标准的发送数据的方法,并且总是表现出以下行为:
var count = 0;
while (count < size)
{
count += socket.Send(buffer, offset + count, size - count, ...);
}
这是什么意思
您可以直接调用Socket::Send
来编写正确可靠的send((代码,而不能通过调用NetworkStream::Write
来编写正确可信的send(代码。
顺便说一句,NetworkStream
的其他变体没有BCL拆卸所显示的相同问题(见mono,cosi2(,尽管他们尽了最大努力,但仍有其他变体显示出类似的问题(见floronefx(。
参考文献
- Github上的Mono存储库
- FlourineFxSL源代码
- BitBucket上的cosi2存储库(通过searchcode.com(