为什么服务器不使用 C# 中的套接字在本地传输中接收所有 UDP 数据包? [英] Why doesn't the server receive all UDP packets in a local transfer using sockets in C#?

查看:43
本文介绍了为什么服务器不使用 C# 中的套接字在本地传输中接收所有 UDP 数据包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个服务器和一个客户端应用程序,客户端向服务器发送一堆数据包.使用的协议是UDP.客户端应用程序生成一个新线程以循环发送数据包.服务器应用程序还会生成一个新线程以在循环中等待数据包.

I have a server and a client application where the client sends a bunch of packets to the server. The protocol used is UDP. The client application spawns a new thread to send the packets in a loop. The server application also spwans a new thread to wait for packets in a loop.

这两个应用程序都需要根据传输进度更新 UI.如何正确保持 UI 更新已通过 这个问题.基本上,服务器和客户端应用程序都会为每次循环迭代引发一个事件(下面的代码),并且两者都会随着进度更新 UI.像这样:

Both of these applications need to keep the UI updated with the transfer progress. How to properly keep the UI updated has been solved with this question. Basically, both the server and client applications will raise an event (code below) for each loop iteration and both will keep the UI updated with the progress. Something like this:

private void EVENTHANDLER_UpdateTransferProgress(long transferedBytes) {
    receivedBytesCount += transferedBytes;
    packetCount++;
}

每个应用程序中的计时器将使用来自 receivedBytesCountpacketCount 的最新信息更新 UI.

A timer in each application will keep the UI updated with the latest info from receivedBytesCount and packetCount.

客户端应用程序完全没有问题,一切似乎都按预期工作,每次发送数据包时 UI 都会正确更新.服务器是有问题的...

The client application has no problems at all, everything seems to be working as expected and the UI is updated properly every time a packet is sent. The server is the problematic one...

传输完成后,receivedBytesCountpacketCount 将与发送的总字节数或客户端发送的数据包数量不匹配.顺便说一下,每个数据包的大小为 512 字节.服务器应用程序在返回来自 Socket.ReceiveFrom() 的调用后立即计算收到的数据包.而且似乎由于某种原因没有收到它应该收到的所有数据包.

When the transfer is complete, receivedBytesCount and packetCount will not match the total size in bytes sent nor the number of packets the client sent. Each packet is 512 bytes in size by the way. The server application is counting the packets received right after the call from Socket.ReceiveFrom() is returned. And it seems that for some reason is not receiving all the packets it should.

我知道我使用的是 UDP,它不能保证数据包实际上会到达目的地,并且不会执行重新传输,因此可能会丢失一些数据包.但我的问题是,由于我实际上是在本地进行测试,服务器/客户端都在同一台机器上,为什么会发生这种情况?

I know that I'm using UDP which doesn't guarantee the packets will actually arrive at the destination and no retransmission will be performed so there might be some packet loss. But my question is, since I'm actually testing this locally, both the server/client are on the same machine, why exactly is this happening?

如果我在客户端发送循环中放置一个 Thread.Sleep(1)(这似乎转换为 15ms 暂停),服务器将接收所有数据包.由于我在本地执行此操作,因此客户端发送数据包的速度太快(没有 Sleep() 调用),服务器无法跟上.这是问题所在还是可能出在其他地方?

If I put a Thread.Sleep(1) (which seems to translates to a 15ms pause) in the client sending loop, the server will receive all the packets. Since I'm doing this locally, the client is sending packets so fast (without the Sleep() call) that the server can't keep up. Is this the problem or it may lie somewhere else?

推荐答案

'如果我在客户端发送循环中放置一个 Thread.Sleep(1)(这似乎转换为 15ms 暂停),服务器将收到所有包'

'If I put a Thread.Sleep(1) (which seems to translates to a 15ms pause) in the client sending loop, the server will receive all the packets'

套接字缓冲区已满,堆栈正在丢弃消息.UDP 没有流量控制,因此,如果您尝试在紧密循环中发送大量数据报,某些数据报将被丢弃.

The socket buffers are getting full and the stack is discarding messages. UDP has no flow-control and so, if you try send a huge number of datagrams in a tight loop, some will be discarded.

使用你的 sleep() 循环,(呃!),在 UDP 之上实现某种形式的流量控制,实现某种形式的非网络流量控制,(例如,使用异步调用、缓冲池和互线程通信),或使用内置流量控制的不同协议.

Use your sleep() loop, (ugh!), implement some form of flow-control on top of UDP, implement some form of non-network flow-control, (eg. using async calls, buffer pools and inter-thread comms), or use a different protocol with flow-control built in.

如果您在网络堆栈中铲除东西的速度比它消化它的速度快,那么它偶尔会出现问题,您应该不会感到惊讶.

If you shovel stuff at the network stack faster than it can digest it, you should not be surprised if it throws up occasionally.

这篇关于为什么服务器不使用 C# 中的套接字在本地传输中接收所有 UDP 数据包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆