- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先让我说这与 UDP 作为协议(protocol)的可靠性无关。我知道数据包可能会被丢弃、乱序到达等。另外,严格来说,这不是数据速率的问题(我不是试图每秒处理太多的数据包),也不是数据量的问题数据(不是客户端底层缓冲区大小的问题)。
我的典型 UDP 监听器如下所示(VB.NET 如下):
Private ListenSocket As System.Net.Sockets.UdpClient
Private UDPSyncResult As System.IAsyncResult
Private UDPState As New Object
Private ReadOnly UDPReadLock As New Object
Private Sub StartListening()
Try
ListenSocket = New System.Net.Sockets.UdpClient
ListenSocket.Client.SetSocketOption( _
Net.Sockets.SocketOptionLevel.Socket, _
Net.Sockets.SocketOptionName.ReuseAddress, True)
ListenSocket.Client.Bind(New System.Net.IPEndPoint( _
System.Net.IPAddress.Any, ListenPort))
UDPSyncResult = ListenSocket.BeginReceive(AddressOf ProcessPacket, _
UDPState)
Catch ex As Exception
'Handle an exception
End Try
End Function
Private Sub ProcessPacket(ByVal ar As IAsyncResult)
SyncLock UDPReadLock
Try
If ar Is UDPSyncResult Then
Dim Data As Byte() = ListenSocket.EndReceive(ar, _
New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0))
ParsePacket(Data)
UDPSyncResult = ListenSocket.BeginReceive( _
AddressOf ProcessPacket, UDPState)
End If
Catch ex As Exception
Try
UDPSyncResult = ListenSocket.BeginReceive( _
AddressOf ProcessPacket, UDPState)
Catch ex2 As Exception
'Do nothing
End Try
End Try
End SyncLock
End Sub
ParsePacket
将是一个对数据执行某些操作的 Sub。
ProcessPacket
被调用两次,但不可避免的是,它会被调用一次,然后再也不会被调用。也就是杀掉整个检测包,调用回调函数机制。
Private Sub StartTalking()
Try
TalkSocket = New System.Net.Sockets.UdpClient
TalkSocket.Connect(System.Net.IPAddress.Parse(TalkIP), _
TalkPort)
Catch ex As Exception
End Try
End Sub
Private Sub SendTwoPackets()
Dim Packet As Byte() = AssemblePacket()
Try
TalkSocket.Send(Packet, Packet.Length)
TalkSocket.Send(Packet, Packet.Length)
Catch ex As Exception
End Try
End Sub
SendTwoPackets
到一个按钮,然后点击离开。
AssemblePacket
将是创建要发送的数据数组的东西。
ar Is UDPSyncResult
的检查上。 ;如果这是
False
,那么我永远不会调用
BeginReceive
再次。所以现在我的回调看起来更像这样:
Private Sub ProcessPacket(ByVal ar As IAsyncResult)
SyncLock UDPReadLock
Try
Dim Data As Byte() = ListenSocket.EndReceive(ar, _
New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0))
ParsePacket(Data)
UDPSyncResult = ListenSocket.BeginReceive( _
AddressOf ProcessPacket, UDPState)
Catch ex As Exception
Try
UDPSyncResult = ListenSocket.BeginReceive( _
AddressOf ProcessPacket, UDPState)
Catch ex2 As Exception
'Do nothing
End Try
End Try
End SyncLock
End Sub
IASyncResult
传递给回调,我从不使用传递给
BeginReceive
的“状态对象” .也许专家可以告诉我写这个回调的“最正确”的方式?
最佳答案
我立即看到了几件事:
你应该只 SyncLock
您的代码在最短的时间内获取数据。不处理。
看起来您还试图在 Try
中重新开始监听。和 Catch
条款。将其移至 Finally
它在这两种情况下都有效。
我要做的最后一件事是制作 ParsePacket
每次调用时都在自己的线程上运行。这样你就不会干扰主线程上的数据接收了。看看 MSDN 上的这篇文章:Walkthrough: Authoring a Simple Multithreaded Component with Visual Basic
我会把它修改成这样的:
Private Sub ProcessPacket(ByVal ar As IAsyncResult)
Dim Data As Byte()
SyncLock UDPReadLock
Try
Data = ListenSocket.EndReceive(ar, _
New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0))
Catch ex As Exception
' Handle any exceptions here
Finally
Try
UDPSyncResult = ListenSocket.BeginReceive( _
AddressOf ProcessPacket, UDPState)
Catch ex As Exception
' Do nothing
End Try
End Try
End SyncLock
' Only attempt to process if we received data
If Data.Length > 0 Then
ParsePacket(Data)
End If
End Sub
关于.NET:如果接收到的数据包靠得太近,UDPClient.BeginReceive() 将无法运行回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21366887/
好吧,假设我有一堆光盘放在已知固定位置的飞机上。每个圆盘的半径为 1 个单位。该平面完全被一组圆盘覆盖,事实上,它被一组圆盘广泛覆盖,在某些区域覆盖了一两个数量级。我想找到仍然完全覆盖飞机的光盘子集。
我有一个涉及大量相关表的系统。考虑一个标准的类别/产品/订单/客户/订单项目场景。有些表是自引用的(如类别)。这些表都不是特别大(大约 10 万行,估计规模约为 100 万行)。我需要考虑这些数据的很
我正在学习 https://near.academy/near101/chapter-6 中的教程 其中一个步骤是运行此命令(但使用我的帐户): near call museum.testnet ad
我正在启动一个分析项目,该项目将处理数百万地理定位数据。数据可能是这样的: 编号{ 用户身份, 长, 纬度, 时间, 应用ID } 我的主要操作: 获取区域中包含的所有数据 找到属于某个userId的
在性能方面,JSON 解析需要大量时间来检索数据。在我的应用程序中,我需要从服务器获取近 10,000 条记录。在模拟器上,它立即获取数据并高效工作。但在我的 android 手机中,它需要超过2 分
任何人都可以帮助我从投影矩阵 44 获得左、右、下、上、近和远边界值吗? 最佳答案 这里是方程组的分辨率 Christian Rau引用: 对于正交矩阵: near = (1+m34)/m33;
我正在通过后台线程将 1,00,000 条记录插入到数据库中。此时,当我想要加载 Ui 屏幕时,出现内存不足错误。例如,当堆大小为 5 MB 且分配给后台线程的内存为 4 MB 时,加载 UI 屏幕需
C++如何存储近100000位的海量数字?.. 我试过使用 long long int 和 long double int..对我没有任何作用.. 有没有其他方法可以存储这么大的数字? 我希望找到大于
我是一名优秀的程序员,十分优秀!