NetworkStream.Write 与 Socket.Send
我有一个 c# 应用程序,我使用自定义 FTP 库。现在我使用 Socket.Send 发送数据,但我想知道使用套接字启动 NetworkStream 并使用 NetworkStream.Write 是否会更好。
使用其中一种比另一种有什么优势吗?
I have a c# application that I use a custom FTP library for. Right now Im using Socket.Send to send the data but I was wondering if it would be better to initiate a NetworkStream with the socket and use NetworkStream.Write instead.
Are there any advantages to using one over the other?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
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
。The advantage of a
NetworkStream
derives primarily from the fact that it is aStream
. The disadvantage of aSocket
is that common code that reads and writes from abstract I/O sources like aStream
cannot handle aSocket
.The main use case for a
NetworkStream
is that you have some code elsewhere that reads or writes from aStream
, and you wish you could use it with aSocket
. You would know if were in this situation and thenNetworkStream
would be a big help!Say for example you had a communications library and you supported serializing messages from files, named pipes and TCP/IP. The ideal choice for the I/O class would be
Stream
. Then your serialization methods could accept aFileStream
, aPipeStream
, or aNetworkStream
. It would even accept aMemoryStream
. This is the benefit of abstraction because after we've created the stream, a method can interact with it without knowing what kind of stream it is.In this sense, a
NetworkStream
uses the adapter design pattern. It adapts theSocket
API to theStream
API so that clients that are expecting aStream
can use it.So finally, the question, if
NetworkStream
is aStream
adapter for aSocket
, which one should we use? Well, if you need aStream
, thenNetworkStream
is your only choice. If you don't need aStream
, then you can use whichever API you are most comfortable with. If you are already usingSocket
successfully, there is no pressing reason to switch toNetworkStream
.您可以单独创建
NetworkStream
并像使用抽象Stream
一样使用它 - 这样您就可以更改传输方式或简单地创建Stream< /code> 用于测试的存根。
作为方法本身的问题 - NetworkStream.Write 内部有唯一的操作(状态检查除外)streamSocket.Send(buffer, offset, size, SocketFlags.None); -所以它与在套接字上调用它基本上相同。
You can potentially separate creation of
NetworkStream
and to work with that as with abstractStream
- so you'll be able to change your transport or simply to createStream
stubs for testing.As a question of method itself -
NetworkStream.Write
inside has the only operation (except state checks)streamSocket.Send(buffer, offset, size, SocketFlags.None);
- so it's mostly the same as to call that on socket.使用 .NET Framework 实现
NetworkStream::Write
的一个缺点是,如果底层网络 (OSI 层 1-4) 无法接收您不知道的整个数据缓冲区(除非,也许通过检查 .NET 网络性能计数器。)不可靠。
类似这样的内容出现在 Microsoft .NET Framework System.dll 的
NetworkStream::Write
中:注意返回值,它表示
Send 写入的字节数()
,被丢弃。这表明 NetworkStream::Write 对于低于标准的网络(漫游/无线)或可能成为 IO 限制(超出可用带宽)的网络来说是不可靠的。 不止一种实现。
您可以找到其他实现,这些实现会写入所有字节,直到所有
buffer
都已写入(或发生其他故障)。这是发送数据的标准方法,并且始终会表现出以下行为:这是什么意思意思是?
您可以通过直接调用
Socket::Send
来编写正确且可靠的send()代码,但不能通过调用NetworkStream::Write
来编写正确且可靠的send()代码。顺便说一句,
NetworkStream
的其他变体并不存在 BCL 反汇编所示的相同问题(请参阅 单声道,cosi2),尽管尽了最大努力,但仍有其他人表现出类似的问题(请参阅flourinefx)。参考
One disadvantage of using the .NET Framework implementation of
NetworkStream::Write
is that if the underlying network (OSI layers 1-4) is unable to receive the entire data buffer you are not made aware (except, perhaps, by inspecting .NET Networking performance counters.)Unreliable.
Something like this appears in
NetworkStream::Write
of Microsoft's .NET Framework System.dll:Note how the return value, which represents the count of bytes written by
Send()
, is discarded. This suggestsNetworkStream::Write
is unreliable for sub-par networks (roaming/wireless), or networks that may become IO bound (exceeding available bandwidth.)More than one implementation.
You can find other implementations which write all bytes until all of
buffer
has been written (or other failure occurs.) It is a standard method of sending data, and will always exhibit the following behavior:What does this mean?
You can write proper and reliable send() code by calling
Socket::Send
directly, you cannot write proper and reliable send() code callingNetworkStream::Write
.As an aside, other variations of
NetworkStream
do not have the same problem the BCL disassembly shows (see mono,cosi2), and still others show similar problems despite their best efforts (see flourinefx).References