我遇到了C#启动时间慢的问题,导致UDP数据包最初丢失。下面,我就是为减轻这种启动延迟所做的工作。我基本上在前两个数据包传输之间再等待10ms。这至少在我的机器上修复了初始下降。我担心的是较慢的机器可能需要比这更长的延迟。
private void FlushPacketsToNetwork()
{
MemoryStream packetStream = new MemoryStream();
while (packetQ.Count != 0)
{
byte[] packetBytes = packetQ.Dequeue().ToArray();
packetStream.Write(packetBytes, 0, packetBytes.Length);
}
byte[] txArray = packetStream.ToArray();
udpSocket.Send(txArray);
txCount++;
ExecuteStartupDelay();
}
// socket takes too long to transmit unless I give it some time to "warm up"
private void ExecuteStartupDelay()
{
if (txCount < 3)
{
timer.SpinWait(10e-3);
}
}
所以,我想知道是否有更好的方法让C#完全加载其所有依赖项?我真的不介意完全加载需要几秒钟;在C#准备好全速运行之前,我只是不想做任何高带宽传输。
这是一个控制台应用程序,网络传输是从一个单独的线程运行的,主线程只是等待按键终止网络传输器。
在Program.Main
方法中,我试图通过使用合理的最高优先级从我的应用程序中获得最大的性能:
public static void Main(string[] args)
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
...
Thread workerThread = new Thread(new ThreadStart(worker.Run));
workerThread.Priority = ThreadPriority.Highest;
workerThread.Start();
...
Console.WriteLine("Press any key to stop the stream...");
WaitForKeyPress();
worker.RequestStop = true;
workerThread.Join();
此外,我目前使用的套接字设置如下所示:
udpSocket = new Socket(targetEndPoint.Address.AddressFamily,
SocketType.Dgram,
ProtocolType.Udp);
udpSocket.Ttl = ttl;
udpSocket.SendBufferSize = 1024 * 1024;
udpSocket.Blocking = true;
udpSocket.Connect(targetEndPoint);
默认SendBufferSize
是8192,所以我继续将其移动到兆字节,但此设置似乎对开始时丢弃的数据包没有任何影响。
答案 0 :(得分:0)
从评论中我了解到TCP不是你的选择(因为传输中存在固有的延迟),你也不想因为其他方没有完全加载而丢失数据包。
因此,您实际上需要实现TCP(重传)中存在的一些功能,但需要更强大和轻量级的方式。我还假设你控制了接收方。
我建议您发送一些预定数量的数据包。然后等待确认。例如,每个数据包都可以具有不断增长的ID。每N个数据包,接收应用程序将最后接收的数据包的数量发送给发送方。收到此号码后,发件人将知道是否有必要重复最后N个数据包。
这种方法不会对你的带宽产生太大影响,你会得到关于接收数据的某种信息(尽管不能保证)。
否则最好切换到TCP。顺便问一下你尝试使用TCP吗?你的带宽伤害了多少?