添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

如何使用c#/.Net的TcpClient发送'n'个数据包

0 人关注

我试图用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);
    
1 个评论
数据包是TCP的 实现 方式,但作为一个用户,你应该完全不知道它们的存在。TCP所展示的抽象概念是一个 无尽的字节流 。如果你想把这个字节流分解成数据包或消息,那就要靠 在无尽的字节流上实现这样的框架(或者转到更高层次的协议上,为你做这些事情)。
c#
.net
sockets
server
tcpclient
Salman Shahid Bukhari
Salman Shahid Bukhari
发布于 2021-09-20
1 个回答
Rowan Smith
Rowan Smith
发布于 2021-09-20
0 人赞同

你不能用TcpClient准确控制数据包的发送。 事实上,你甚至不能用TCP Socket()来做这件事。 你需要使用一个Raw 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 ,以及为什么它是TCP协议的一个固有部分。

顺便提一下,stream.Flush();NetworkStream.Flush() 完全没有作用。 这是它在.Net源中的实现。

    /// <devdoc>
    ///    <para>
    ///       Flushes data from the stream.  This is meaningless for us, so it does nothing.