NetworkStream.Write 与 Socket.Send

发布于 2024-11-18 12:46:53 字数 139 浏览 1 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

锦上情书 2024-11-25 12:46:53

NetworkStream 的优势主要源于它是一个StreamSocket 的缺点是从抽象 I/O 源(如 Stream)读取和写入的通用代码无法处理 Socket

NetworkStream 的主要用例是,您在其他地方有一些从 Stream 读取或写入的代码,并且您希望可以将其与 Socket 一起使用/代码>。您会知道如果处于这种情况,那么 NetworkStream 将提供很大帮助!

举例来说,您有一个通信库,并且支持从文件、命名管道和 TCP/IP 序列化消息。 I/O 类的理想选择是 Stream。然后,您的序列化方法可以接受 FileStreamPipeStreamNetworkStream。它甚至会接受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 a Stream. The disadvantage of a Socket is that common code that reads and writes from abstract I/O sources like a Stream cannot handle a Socket.

The main use case for a NetworkStream is that you have some code elsewhere that reads or writes from a Stream, and you wish you could use it with a Socket. You would know if were in this situation and then NetworkStream 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 a FileStream, a PipeStream, or a NetworkStream. It would even accept a MemoryStream. 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 the Socket API to the Stream API so that clients that are expecting a Stream can use it.

So finally, the question, if NetworkStream is a Stream adapter for a Socket, which one should we use? Well, if you need a Stream, then NetworkStream is your only choice. If you don't need a Stream, then you can use whichever API you are most comfortable with. If you are already using Socket successfully, there is no pressing reason to switch to NetworkStream.

不再让梦枯萎 2024-11-25 12:46:53

您可以单独创建 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 abstract Stream - so you'll be able to change your transport or simply to create Stream 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.

゛时过境迁 2024-11-25 12:46:53

使用 .NET Framework 实现 NetworkStream::Write 的一个缺点是,如果底层网络 (OSI 层 1-4) 无法接收您不知道的整个数据缓冲区(除非,也许通过检查 .NET 网络性能计数器。)

不可靠。

类似这样的内容出现在 Microsoft .NET Framework System.dllNetworkStream::Write 中:

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 反汇编所示的相同问题(请参阅 单声道,cosi2),尽管尽了最大努力,但仍有其他人表现出类似的问题(请参阅flourinefx)。

参考

  1. Github 上的 Mono 存储库
  2. FlourineFxSL 源代码
  3. BitBucket 上的 cosi2 存储库(通过 searchcode .com)

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:

try
{
    socket.Send(buffer, offset, size, SocketFlags.None);
}
/* ... catch{throw;} */

Note how the return value, which represents the count of bytes written by Send(), is discarded. This suggests NetworkStream::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:

var count = 0;
while (count < size)
{
    count += socket.Send(buffer, offset + count, size - count, ...);
}

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 calling NetworkStream::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

  1. Mono Repository on Github
  2. FlourineFxSL Source Code
  3. cosi2 Repository on BitBucket (via searchcode.com)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文