数据通过Receive方法发送但未被接收会发生什么?

huangapple go评论67阅读模式
英文:

What happens to data sent but not received with the Receive method?

问题

如果我实现了一个服务器和一个客户端,其中一个发送了 'N' 个数据,但另一方没有调用 'Receive' 方法,那么传输的数据存在于哪里?

我实现了一个简单的服务器和客户端,其中一个定期使用 'Send' 方法发送数据,另一个在特定的时间后连续调用 'Receive'。

虽然我还没有确认大量数据,但我成功地接收了大约 2000 个项目的稳定连续传输。

一旦我开始调用 'Receive',就按顺序接收了总共 2000 个数据(每个数据大小为 1024 字节),以及随后的数据 2001 和 2002。

我好奇在调用 'Receive' 之前的大约 2000 个数据的来源。

英文:

I have a basic question that has come up, so I would like to ask them.

If I implement a server and a client, and one of them sends 'N' number of data but the other side does not invoke the Receive method, where does the transmitted data exist?

I have implemented a simple server and client, where one of them periodically sends data using the Send method, and the other continuously invokes Receive at after a specific timing.

Although I haven't confirmed with a large amount of data, I was able to receive a stable sequential transmission of up to approximately 2000 items.

As soon as I started invoking Receive, a total of 2000 data (each 1024 bytes) were received along with the subsequent data 2001 and 2002 in sequential order.

I am curious about the origin of the preceding approximately 2000 data received before invoking Receive.

答案1

得分: 2

一般情况下,网络堆栈在不同层次上都有缓冲区,可以存储一定量的数据。

当数据被网络卡接收时,它会将数据缓冲(可以直接存入RAM,使用DMA协议,完全绕过CPU,或者存入卡上的内部缓冲区)。然后,它会向CPU发出信号(中断),告知数据已经可用。

CPU会停止当前操作,允许网络驱动程序和内核处理数据。内核会查找哪些TCP套接字是打开的,以便知道要将数据发送到哪里。通常,适当的用户模式应用程序会有一个等待线程,它会被唤醒以接收数据(所有这些操作都发生在“接收”方法内部)。

当“接收”方法被唤醒以完成时,它会请求将数据复制到用户模式缓冲区中(通常由您在C#中提供,尽管通常还可以有更多层次的缓冲区在其中)。

所以,如果您不调用“接收”,数据将简单地停留在内核模式缓冲区中,直到您请求获取它。如果缓冲区已满,那么数据包将被丢弃,引发大量的连接问题。可以说,TCP被设计为可靠的数据流,不喜欢丢包。

这就是为什么您应该尽快处理网络数据的原因。将其从等待数据的线程中取出,以便您可以继续等待更多数据。

英文:

Generally, the networking stack has buffers at various levels that can store a certain amount of data.

When data is received by the network card, it buffers that data (either directly into RAM, using DMA protocols, completely bypassing the CPU, or in internal buffers on the card). It then signals (interrupts) the CPU that data is available.

The CPU stops what it's doing and allows the network driver and kernel to deal with the data. The kernel then looks up what TCP sockets are open so it knows where to send the data. The appropriate user-mode application normally has a waiting thread, that gets woken up to receive the data (this all happens within the Receive method).

When the Receive is woken up to complete, it will request that the data is copied into a user-mode buffer (usually supplied by you from C#, although there can often be more levels of buffers in between).


So if you don't call Receive, the data will simply sit in the kernel-mode buffer until you ask for it. If the buffer is full then the packets will simply be dropped, causing lots of connectivity issues. Suffice to say, TCP is meant to be a reliable stream, and does not like dropped packets.

This is why you should deal with your network data as fast as possible. Get it off the thread that is waiting for the data, so that you can continue waiting for more.

huangapple
  • 本文由 发表于 2023年5月28日 11:12:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76349789.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定