【问题标题】:How to send 'n' Number of packets using TcpClient using c#/.Net如何使用 C#/.Net 使用 TcpClient 发送“n”个数据包
【发布时间】:2021-11-14 03:01:25
【问题描述】:

我正在尝试使用 TcpClient 发送多个数据包。此代码适用于第一次迭代。但是在第一次迭代之后,服务器没有收到任何东西(尽管循环不断迭代)。服务器端代码运行良好,因为我一直在使用数据包发送方对其进行测试。有什么可以使用 TcpClient 发送突发数据包吗?

TcpClient tcpClient = new TcpClient(localIpAddress,localPort);
            tcpClient.NoDelay = true;
            tcpClient.Connect(remoteIpAddress,remotePort);
            Stream stream=tcpClient.GetStream();
            int i = 0;
            while (true)
            {
                i = i + 1;
                Console.WriteLine("Message {0} Sent",i);
                stream.Write(Encoding.ASCII.GetBytes(message))));
                stream.Flush();
                Thread.Sleep(500);
                
            } 

【问题讨论】:

  • 数据包是 TCP 的实现方式,但作为用户,您应该完全不了解它们。 TCP 公开的抽象是无尽的字节流。如果您想将该流分解为数据包或消息,则由在无穷无尽的字节流上实现这种框架(或转移到为您执行此操作的更高级别的协议)跨度>

标签: c# .net sockets server tcpclient


【解决方案1】:

您无法使用 TcpClient 准确控制数据包的发送。事实上,你甚至不能用 TCP Socket() 来做到这一点。您需要使用原始套接字并构建自己的 TCP 数据包。

TCP 堆栈根据套接字配置选项、缓冲区中的信息量、最后一次 ACK 的时间、窗口大小、RTT 以及其他一些信息来决定何时发送数据包.

您可以通过发送大量数据来伪造它,这将迫使 TCP 堆栈以尽可能快的速度立即发送它们。您也可以设置TcpClient.NoDelay(),但这不适用于多次连续写入,除非您在写入之间有合理的延迟,即使这样也不能保证。

您可以进行低级别调用来计算发送/接收的数据包数量,但您只能通过调整 TCP 堆栈的参数来影响这一点,即使这样它也永远不会是确定性的,因为 IP 是有损协议和 TCP 数据包会丢失,需要重新传输。

您对上面代码的问题是您正在使用此行设置 LocalEndPoint:

TcpClient tcpClient = new TcpClient(localIpAddress,localPort);

在套接字通过TIME_WAIT 阶段之前,端口将无法重用,这取决于套接字关闭的时间可能为 120 秒。

将该行更改为:

TcpClient tcpClient = new TcpClient(); 

或者如果你必须设置源IP地址

TcpClient tcpClient = new TcpClient(localIpAddress,0);

您可以阅读TIME_WAIT here 以及它为何是 TCP 协议的固有部分。

作为旁注,stream.Flush();NetworkStream.Flush() 绝对没有任何作用。这是它在 .Net 源代码中的实现:

    /// <devdoc>
    ///    <para>
    ///       Flushes data from the stream.  This is meaningless for us, so it does nothing.
    ///    </para>
    /// </devdoc>
    public override void Flush() {
    }

【讨论】:

  • 实际上我正在尝试开发一个仅使用单个端口发送数据包的数据包发送器。所以在代码更改方面的任何帮助将不胜感激!
  • 如果你想设置源端口,并且每次都想启动一个新的连接,那么你需要等待旧的连接从TCP堆栈中超时,然后才能重用它.这是设计使然,是 TCP 协议的一部分。
  • 当我只需要在同一个连接上发送多个数据包时,为什么还要等待旧连接完成?
  • 我上面包含的链接解释了拆卸过程,延迟是 TCP 堆栈的一部分。如果您想在 TIME_WAIT 过期之前重用源端口,则无法避免这种情况,这可能是 0 秒到 120 秒,具体取决于网络上套接字关闭的发生方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 2011-04-07
  • 1970-01-01
  • 2015-04-16
相关资源
最近更新 更多