UDP Socket稳定发送,突发接收
我设置了一个非常简单的 UdpClient 来尽可能快地接收 8 字节的数据。客户端发送数据的速度非常快,但服务器接收数据的时间间隔非常不稳定,大约为 0.5 秒。它在接收时停止,然后突然非常快地连续接收大约十个数据报,然后再次停止大约 0.5 秒,依此类推。这里可能有什么问题?我尝试关闭防火墙,但没有帮助...
客户端:
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
此代码不断发送累积的缓冲区:
if (!_sending)
{
_sending = true;
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += (s2, e2) => { _sending = false; };
args.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.100"), 14123);
args.SetBuffer(buffer, 0, buffer.Length);
_socket.SendToAsync(args);
}
服务器:
UdpClient udp = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.0.100"), 14123));
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
byte[] buffer = udp.Receive(ref endpoint);
int x = BitConverter.ToInt32(buffer, 0);
int y = BitConverter.ToInt32(buffer, 4);
Console.WriteLine(string.Format("Receiving x={0}, y={1} @ {2}", x, y, DateTime.Now.Ticks));
}
我现在知道它非常原始的代码,但它至少没有抛出任何异常...
我已经检查过 Wireshark 但我不确定到底要寻找什么。 UDP 消息发送正常,没有出现问题。
我读过限制 UDP 而不是尽可能快地发送是个好主意。我确实尝试过,没有任何明显的差异。发送速度较慢,但接收速度和以前一样厚实/突发。
客户端和接收器都在同一台开发机器上(Windows 7)。
以下是测量接收呼叫之间的时间的一些输出。正如您所看到的,它大约每 30 次迭代就会卡住一秒钟:
1,0180582
0,001
0
0
0,0010001
0
0
0
0
0,0010001
0
0
0
0
0
0
0
0
0
0
0,0010001
0
0
0
0
0
0,0010001
1,0170582
等等
更新
看起来延迟是在发送缓冲区后出现的。发送代码似乎非常快速/流畅地发送缓冲区,但是当它们出现在 Wireshark 中时,它们大约每秒触发 udp 就会有 1 秒的延迟。接收代码似乎并没有导致这种延迟,它已经准备好了。我不明白。
I've setup a very simple UdpClient to receive 8 bytes of data as fast as possible. The client is sending the data very fast but the server is receiving it in very choppy intervals of about 0.5 seconds. It stops on receive and then suddenly receives about ten datagrams in a row very fast, then stops again for ~0.5 seconds and so on. What could be the problem here? Ive tried turning off the firewall but it didnt help...
Client:
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
This code is continuously sending an accumulated buffer:
if (!_sending)
{
_sending = true;
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += (s2, e2) => { _sending = false; };
args.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.100"), 14123);
args.SetBuffer(buffer, 0, buffer.Length);
_socket.SendToAsync(args);
}
Server:
UdpClient udp = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.0.100"), 14123));
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
byte[] buffer = udp.Receive(ref endpoint);
int x = BitConverter.ToInt32(buffer, 0);
int y = BitConverter.ToInt32(buffer, 4);
Console.WriteLine(string.Format("Receiving x={0}, y={1} @ {2}", x, y, DateTime.Now.Ticks));
}
I know its very primitive code right now but its at least not throwing any exceptions...
Ive checked with Wireshark but I not sure exactly what to look for. The UDP messages get sent alright, without hiccups.
Ive read its a good idea to throttle UDP and not send as fast as possible. I did try that without any noticable difference. The sending is slower but the receiving is as chunky/bursty as before.
Both client and receiver is on the same dev-machine (Windows 7).
Here's some output from measuring the time (s) between Receive-calls. As you can see it get stuck for one second about every 30 iterations:
1,0180582
0,001
0
0
0,0010001
0
0
0
0
0,0010001
0
0
0
0
0
0
0
0
0
0
0,0010001
0
0
0
0
0
0,0010001
1,0170582
etc
Update
It looks like the delay arise after the buffers has been sent. The sending code seem to send the buffers very rapidly/fluidly, but when they appear in Wireshark they have a 1 second delay about every second of udp-firing. The receiving code doesnt seem to be casuing this delay, it is allready there. I dont get it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在我看来,通过使用 .Net 异步 I/O,您放弃了对发送时间的控制。我不知道这个异步设施中内置了什么样的延迟,但我的猜测是涉及一些后台线程池,并且这些线程正在轮询一些输入队列。
我会尽力避免所有这些开销,只处理在同一线程中发送。 UDP非常简单,只需发送然后忘记,尤其是在处理单个套接字时。我认为这里不需要异步 I/O 开销。
Seems to me that by using .Net asynchronous I/O you are giving away control of the send timing. I don't know what sort of delays are built into this async facility, but my guess is that some background thread pool is involved and those threads are polling some input queue.
I'd try to avoid all that overhead and just deal with sending in the same thread. UDP is very simple, just send and forget, especially when dealing with a single socket. I don't think async I/O overhead is needed here.