C# 字节仅在代码末尾发送.[套接字]



我是C#的新手,这是我的第一个代码:D我过去在 Java 中嘘教,现在我在发送套接字时遇到了很多麻烦。 当我尝试发送套接字时,它仅在代码的总末尾发送: 例如

using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
namespace HelloWorld
{
class Program
{
public static TcpClient client;
public static NetworkStream networkStream;
public static void Main(string[] args)
{
client = new TcpClient("62.210.130.212", 35025);
networkStream = client.GetStream();
byte[] usernameBytes = Encoding.ASCII.GetBytes("This is just a test bro!");
networkStream.Write(usernameBytes, 0, usernameBytes.Length);
networkStream.Flush();
while (true)
{
// Infinte loop
}
// THE SOCKER WILL ONLY BE SENT HERE, AT THE END OF THE CODE, WHY ?!
}
}
}

这里只会在关闭程序时发送套接字(因为 wile 循环)

和这里

using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
namespace HelloWorld
{
class Program
{
public static TcpClient client;
public static NetworkStream networkStream;
public static void Main(string[] args)
{
client = new TcpClient("62.210.130.212", 35025);
networkStream = client.GetStream();
byte[] usernameBytes = Encoding.ASCII.GetBytes("This is just a test bro!");
networkStream.Write(usernameBytes, 0, usernameBytes.Length);
networkStream.Flush();
}
}
}

在这种情况下,它将直接发送,因为它是代码的结尾......

有谁知道为什么会发生这种情况以及如何解决它?我希望我的套接字在运行时间的任何时间发送,而不仅仅是在最后:D

谢谢!感谢您阅读这个问题,直到那里。 朱利安。

有谁知道为什么会发生这种情况以及如何解决它?我希望我的套接字在运行时间的任何时间发送,而不仅仅是在最后发送。

为什么会这样?

由于 Nagle 的算法,传输将短暂延迟(以毫秒为单位)。

这意味着您的代码在进入循环之前没有提供足够的时间。

networkStream.Write(usernameBytes, 0, usernameBytes.Length);
networkStream.Flush();
// the time between here is not enough for nagle's algorithm to complete
while (true) { } // blocks the thread from doing any more work
// so, it will end up sending here instead.

如何解决?

快速解决方案 - 禁用 Nagle 算法

如本答案中所述,您可以将TcpClient.NoDelay设置为true以禁用 Nagle 算法。

您可以通过将其添加到代码中来轻松实现此目的:

client = new TcpClient("62.210.130.212", 35025);
client.NoDelay = true; // add this line of code to disable Nagle's algorithm

注意:此解决方案将强制立即发送。但是,由于您的问题不清楚确切的要求,请注意,这可能不是"最佳"解决方案。

更好的解决方案 - 通过处置资源强制执行

如果您处置/关闭TcpClient它将完成相同的操作。此外,它还将提供额外的(以及更好的做法),即在使用完资源后立即释放资源。

public static void Main(string[] args)
{
using (TcpClient client = new TcpClient("62.210.130.212", 35025))
using (NetworkStream networkStream = client.GetStream())
{
byte[] usernameBytes = Encoding.ASCII.GetBytes("This is just a test bro!");
networkStream.Write(usernameBytes, 0, usernameBytes.Length);
}
while (true) { } // loop infinitely
}

注意:这实际上并不像上面的解决方案那样立即发送数据包,而是强制数据包发送,因为我们正在关闭它。但是,在您的情况下,结果是相同的效果,这是您应该练习的更好的方法。


什么是内格尔算法?

Nagle 算法旨在通过使套接字缓冲小数据包,然后在某些情况下将它们组合并发送到一个数据包中来减少网络流量。

TCP 数据包由 40 字节的标头加上正在发送的数据组成。当使用 TCP 发送小数据包时,TCP 标头产生的开销可能成为网络流量的重要组成部分。在负载较重的网络上,此开销导致的拥塞可能导致数据报和重新传输丢失,以及拥塞导致的传播时间过长。Nagle 算法禁止发送新的 TCP 段当新的传出数据从用户到达时,如果连接上以前传输的任何数据仍未确认。

大多数网络应用程序应该使用 Nagle 算法。

在用户数据报协议 (UDP) 套接字上设置此属性将不起作用。

相关内容

  • 没有找到相关文章

最新更新