- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下代码等待通过 UDP 的数据。我有一个测试函数,可以发送 1000 个数据包(数据报?),每个数据包 500 字节。每次我运行测试函数时,接收器仅收到前几十个数据包,但丢弃其余的数据包。我使用 Wireshark 查看了传入的网络数据,发现所有 1000 个数据包实际上都已收到,但只是没有进入可能的应用程序代码。
以下是一些相关的 VB.NET 3.5 代码:
Private _UdbBuffer As Byte()
Private _ReceiveSocket As Socket
Private _NumReceived As Integer = 0
Private _StopWaitHandle As AutoResetEvent
Private Sub UdpListen()
_StopWaitHandle = New AutoResetEvent(False)
_UdpEndPoint = New Net.IPEndPoint(Net.IPAddress.Any, UDP_PORT_NUM)
_ReceiveSocket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
_ReceiveSocket.Bind(_UdpEndPoint)
ReDim _UdbBuffer(10000)
While Not _StopRequested
Dim ir As IAsyncResult = _ReceiveSocket.BeginReceive(_UdbBuffer, 0, 10000, SocketFlags.None, AddressOf UdpReceive, Nothing)
If Not _StopRequested Then
Dim waitHandles() As WaitHandle = {_StopWaitHandle, ir.AsyncWaitHandle}
If (WaitHandle.WaitAny(waitHandles) = 0) Then
Exit While
End If
End If
End While
_ReceiveSocket.Close()
End Sub
Private Sub UdpReceive(ByVal ar As IAsyncResult)
Dim len As Integer
If ar.IsCompleted Then
len = _ReceiveSocket.EndReceive(ar)
Threading.Interlocked.Increment(_NumReceived)
RaiseStatus("Got " & _NumReceived & " packets")
End If
End Sub
我发送的数据如下(暂时不关心数据包内容):
For i as UShort = 0 to 999
Dim b(500) as Byte
_UdpClient.Send(b, b.Length)
Next
如果我在每次调用 Send 之后添加一个小的延迟,更多的数据包会通过;然而,由于 Wireshark 说无论如何都已收到,看来问题出在我的接收代码中。我应该提到 UdpListen 是在单独的线程上运行的。
知道为什么我会丢包吗?我也尝试过 UdpClient.BeginReceive/EndReceive 但遇到了同样的问题。
困扰我的第二个问题是使用套接字时接收缓冲区的全局性质,我不确定是否处理传入数据包的速度不够快,以致缓冲区会被覆盖。还不知道该怎么办,但我愿意接受建议。
9 月 26 日:更新
<小时/>根据对这篇文章和其他帖子的回复中提出的各种有些相互冲突的建议,我对我的代码做了一些更改。感谢所有参与各种事件的人;我现在从拨号到快速以太网获取所有数据包。正如您所看到的,这是我的代码有问题,而不是 UDP 丢弃数据包的事实(事实上,自从我修复以来,我还没有看到超过很小比例的数据包被丢弃或乱序)。
差异:
1) 将 BeginReceive()/EndReceive() 替换为 BeginReceiveFrom()/EndReceiveFrom()。但这本身并没有产生明显的影响。
2) 链接 BeginReceiveFrom() 调用,而不是等待异步句柄设置。不确定这里是否有任何好处。
3) 将 Socket.ReceiveBufferSize 显式设置为 500000,这足以以快速以太网速度传输 1 秒的数据。事实证明,这是一个与传递给 BeginReceiveFrom() 的缓冲区不同的缓冲区。这是最大的好处。
4) 我还修改了发送例程,在发送一定数量的字节后根据预期带宽进行限制,等待几毫秒。这对我的接收代码有很大的好处,尽管 Wireshark 说即使没有这种延迟,我的所有数据仍然可以通过。
我最终没有使用单独的处理线程,因为据我了解,每次调用 BeginReceiveFrom 都会在新的工作线程上调用我的回调。这意味着我可以同时运行多个回调。这也意味着一旦我调用 BeginReceiveFrom,我就有时间做我的事情(只要我不花太长时间并耗尽可用的工作线程)。
Private Sub StartUdpListen()
_UdpEndPoint = New Net.IPEndPoint(Net.IPAddress.Any, UDP_PORT_NUM)
_ReceiveSocket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
_ReceiveSocket.ReceiveBufferSize = 500000
_ReceiveSocket.Bind(_UdpEndPoint)
ReDim _Buffer(50000)
_ReceiveSocket.BeginReceiveFrom(_Buffer, 0, _Buffer.Length, SocketFlags.None, _UdpEndPoint, AddressOf UdpReceive, Nothing)
End Sub
Private Sub UdpReceive(ByVal ar As IAsyncResult)
Dim len As Integer = _ReceiveSocket.EndReceiveFrom(ar, _UdpEndPoint)
Threading.Interlocked.Increment(udpreceived)
Dim receiveBytes As Byte()
ReDim receiveBytes(len - 1)
System.Buffer.BlockCopy(_Buffer, 0, receiveBytes, 0, len)
_ReceiveSocket.BeginReceiveFrom(_Buffer, 0, _UdbBuffer.Length, SocketFlags.None, _UdpEndPoint, AddressOf UdpReceive, Nothing)
//' At this point, do what we need to do with the data in the receiveBytes buffer
Trace.WriteLine("count=" & udpreceived)
End Sub
上面没有显示的是错误处理和UDP数据乱序或丢失的处理。
我认为这可以解决我的问题,但如果有人仍然认为上述内容有任何问题(或者我可以做得更好),我很想听听。
最佳答案
UDP 可以随时丢弃数据包。在这种情况下,您可以尝试在接收器处设置更大的套接字接收缓冲区来缓解。
关于.net - 为什么 Socket.BeginReceive 会丢失 UDP 数据包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3793104/
当然,如果没有数据,BeginReceive() 将永远不会结束。MSDN suggests调用 Close() 会中止 BeginReceive()。 但是,在套接字上调用 Close() 也会对其
我用BeginReceive()方法监听特定的端口。 如何找到发件人的IP? 谢谢你。 最佳答案 我认为您应该详细说明您的问题。 无论如何,您都可以在清晰而详细的"Asynchronous Serve
我有一个用 C# 编写的简单异步套接字服务器(几乎是 Microsoft 的 example ),但是这个示例的问题是它只接受来自客户端的一条消息,然后关闭。我希望此服务器在收到任何消息后保持事件状态
据说 BeginReceive 和 BeginSend 回调不会在 .Net ThreadPool 上执行,而是在 上执行IOCP 线程池。对于高性能服务器,IOCP 线程尽快返回池至关重要,这意味着
基本上我已经建立了套接字连接。这是我的 WaitData 方法: public void WaitForData() { State state = new State
当读取未完成时,读取缓冲区有问题。 如果接收到的 XML 数据是有效的,那么我没有问题。但是,当接收到的 XML 数据不正确时,我正在等待数据的第二部分,然后出现错误。 我的代码如下: int cur
如果客户端通过同一个套接字向服务器发送多条消息,服务器端的 EndReceive 是否会将消息分开,或者服务器是否有可能在单个 BeginReceive 中接收来自两个单独发送的部分消息? 最佳答案
我目前有一个后台线程。在这个线程中是一个无限循环。 这个循环偶尔更新数据库中的一些值,然后在 MessageQueue 上监听 1 秒(使用 queue.Receive(TimeSpan.FromSe
要从套接字异步接收数据,.Net 支持对称的 BeginReceive/EndReceive 调用。基本上你调用BeginReceive()开始监听并确定数据到达时应调用的回调。在回调中调用 EndR
我想做这个 for (int i = 0; i 0 以确定在执行 UdpClient.Receive() 之前是否有任何 UDP 请求排队- 这完全消除了阻塞方面。我确实建议您谨慎尝试此操作,因为此
Socket.BeginReceive/EndReceive 函数的调用顺序是什么? 例如,我两次调用 BeginReceive,一次是为了获取消息长度,第二次是为了获取消息本身。现在的场景是这样的,
在 F# 中使用原始套接字编写异步 Ping,以使用尽可能少的线程启用并行请求。不使用“System.Net.NetworkInformation.Ping”,因为它似乎为每个请求分配一个线程。我也对
我需要接收异步消息。 在所有消息中,前 2 个字节表示下一个字节数组的长度。我的问题是在少数情况下我会收到意外的数据包。 如果我使用 Thread.Sleep(200)这个问题不会发生,或者很少发生。
首先让我说这与 UDP 作为协议(protocol)的可靠性无关。我知道数据包可能会被丢弃、乱序到达等。另外,严格来说,这不是数据速率的问题(我不是试图每秒处理太多的数据包),也不是数据量的问题数据(
我正在使用 UDPClient 发送多播请求并接收来自网络上各种客户端的响应。我能够发送请求并得到响应,但是我得到的响应非常慢。需要 2-3 分钟才能得到所有客户端的响应。在我检查 WireShark
问题: 当我做这样的事情时: for (int i = 0; i < 100; i++) { SendMessage( sometSocket, i.ToString()); Thre
嗨堆栈溢出成员。我正在努力处理一些简单的代码,但无法完成。我有这个等待连接的异步服务器。 while (clientSocket.Connected) { try
我在简单的 Udp 服务器中使用 UdpClient。 是否可以仅从特定的 IP 地址接收 BeginReceive()? 谢谢 最佳答案 没有。这是 UDP 的基础,它不像 TCP 那样是面向连接的
好的,这是我的第一个堆栈溢出问题,所以请随时提出更好的提问方式或我下次应该包括的内容。大多数时候我可以通过谷歌获得答案,但这个有点棘手...... 我正在用 C# 编写一个 Windows 应用程序,
我的 TCP ping/pong 工作正常,但在尝试添加第二种数据类型后,我遇到了接收程序从未触发 BeginReceive 回调的情况。 代码是相同的,除了第二个(有问题的)数据类型,序列化是提前完
我是一名优秀的程序员,十分优秀!