gpt4 book ai didi

c# - UDP发送的数据存储在哪里?

转载 作者:太空狗 更新时间:2023-10-29 19:44:17 27 4
gpt4 key购买 nike

我以前从未使用过 UDP,所以我试了一下。为了看看会发生什么,我让“服务器”每半秒发送一次数据,客户端每 3 秒接收一次数据。因此,即使服务器发送数据的速度比客户端接收数据的速度快得多,客户端仍然会一个接一个地整齐地接收数据。

谁能解释为什么/如何发生这种情况?数据到底缓冲在哪里?

发送

class CSimpleSend
{
CSomeObjServer obj = new CSomeObjServer();

public CSimpleSend()
{
obj.changedVar = varUpdated;
obj.threadedChangeSomeVar();
}

private void varUpdated(int var)
{
string send = var.ToString();
byte[] packetData = System.Text.UTF8Encoding.UTF8.GetBytes(send);

string ip = "127.0.0.1";
int port = 11000;

IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ip), port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
client.SendTo(packetData, ep);

Console.WriteLine("Sent Message: " + send);
Thread.Sleep(100);
}
}

CSomeObjServer 所做的就是每半秒将一个整数递增 1

接收

class CSimpleReceive
{
CSomeObjClient obj = new CSomeObjClient();

public Action<string> showMessage;
Int32 port = 11000;
UdpClient udpClient;


public CSimpleReceive()
{
udpClient = new UdpClient(port);

showMessage = Console.WriteLine;
Thread t = new Thread(() => ReceiveMessage());
t.Start();
}

private void ReceiveMessage()
{
while (true)
{
//Thread.Sleep(1000);
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, port);
byte[] content = udpClient.Receive(ref remoteIPEndPoint);

if (content.Length > 0)
{
string message = Encoding.UTF8.GetString(content);
if (showMessage != null)
showMessage("Recv:" + message);

int var_out = -1;
bool succ = Int32.TryParse(message, out var_out);
if (succ)
{
obj.alterSomeVar(var_out);
Console.WriteLine("Altered var to :" + var_out);
}
}
Thread.Sleep(3000);
}
}
}

CSomeObjClient 存储变量并有一个函数 (alterSomeVar) 来更新它

输出:

Sent Message: 1
Recv:1
Altered var to :1
Sent Message: 2
Sent Message: 3
Sent Message: 4
Sent Message: 5
Recv:2
Altered var to :2
Sent Message: 6
Sent Message: 7
Sent Message: 8
Sent Message: 9
Sent Message: 10
Recv:3
Altered var to :3

最佳答案

操作系统内核为每个 UDP 和 TCP 套接字维护单独的发送和接收缓冲区。如果你用谷歌搜索 SO_SNDBUFSO_RCVBUF,你会发现很多关于它们的信息。

当您发送数据时,它会从您的应用程序空间复制到发送缓冲区。从那里它被复制到网络接口(interface)卡,然后到电线上。接收端是相反的:NIC 接收缓冲区,它在那里等待直到您读取它。此外,还可能发生复制和缓冲,具体取决于操作系统。

重要的是要注意这些缓冲区的大小可能有很大的不同。某些系统可能默认为 4 KB,而其他系统可能默认为 2 MB。您可以使用 getsockopt()SO_SNDBUFSO_RCVBUF 找到当前大小,同样使用 setsockopt() 设置它.但是许多系统限制缓冲区的大小,有时限制为任意小的数量。这通常是一个内核值,如 net.core.wmem_maxnet.core.rmem_max,但具体引用值因系统而异。

另请注意,即使您请求的金额小于假定的限制,setsockopt() 也可能会失败。因此,要实际获得所需的大小,您需要使用递减的数量重复调用 setsockopt(),直到最终成功。

下一页是我公司的技术说明,其中略微涉及到这个主题并提供了一些常见系统的引用:http://www.dataexpedition.com/support/notes/tn0024.html

关于c# - UDP发送的数据存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12300008/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com