Sto*_*ind 5 c# sockets asynchronous
这是一个 Windows .net烦恼,我花了 2 天时间才解决。我发现解决方案很重要,可以在 SO 上为自己喋喋不休,即。给别人一个明确的陈述。如何。
问题:我没有使用 ReceiveAsync() 获得无连接 (UDP) 套接字的发送方 IP 地址。
.net 提供了很好的高性能Receive[...]Async方法,这些方法比传统的 BeginGetResponce ->(回调)-> BeginReceive ->(回调)-> EndReceive 的异步方法链更具优势,因为 Receive[. ..]异步方法重用SocketAsyncEventArgs。您可以维护一个 SocketAsyncEventArgs 池并将它们中的任何一个传递给 Receive[...]Async。当 Receive[...]Async 引发 Completed 回调时,SocketAsyncEventArgs(及其 Buffer 属性)为您提供有效负载。重用影响.net垃圾袋。
但是: SocketAsyncEventArgs。RemoteEndPoint产生异常。和 SocketAsyncEventArgs 一样。ReceiveMessageFromPacketInfo东西。用 (IPAddress.Any 0) 预填充 RemoteEndPoint 只会导致 RemoteEndPoint 说 0.0.0.0:0 - 没用!执行 SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, True) 没有效果。似乎不是获取远程 IP 地址的该死的方法。
网络上充满了问题。但是没有具体的答案。SO 确实为问题提供了答案(主要是 1 好 1,现在我知道要寻找什么了),但也有很多无关紧要的模糊问题。
下面回答。
ReceiveAsync - 不去
ReceiveFromAsync - 不去
ReceiveMessageFromAsync - 去
这些方法的设计和外观几乎相同。Ofc 首先尝试 ReceiveAsync。一个 ReceiveAsyncWithHeaderInfo 引起了我的注意......
A. 沿着这个做套接字创建:
so = Socket.New(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Run Code Online (Sandbox Code Playgroud)
B. 另外(伪),做一个:
so.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, True)
Run Code Online (Sandbox Code Playgroud)
在将套接字绑定到本地端点之前。这并不重要,因为第一个Completed回调无论如何都会将其设置为 True。但是如果没有提前设置,你会丢失第一个数据包。
C. 为 ReceiveMessageFromAsync 构造 SocketAsyncEventArgs 时,将其 RemoteEndPoint 属性设置为
SocketAsyncEventArgs.RemoteEndPoint = IPEndPoint.New(IPAddress.Any, 0)
Run Code Online (Sandbox Code Playgroud)
如果未设置,ReceiveMessageFromAsync 将崩溃,因此这很关键。IPAddress.Any 和端口 0 并不重要,.net 会在数据进来时更新它们,因此设置 RemoteEndPoint 仅提供 Microsoft 空间来写入。哈利路亚。
(D. 并自然地在 SocketAsyncEventArgs 中创建缓冲区和回调,如各种示例所示)
_ _
MS 可以将此注释添加到 no-go 方法的文档中:
“如果您需要发件人 IP 地址(您可能会这样做),请不要使用 ReceiveAsync 或 ReceiveFromAsync,请使用 ReceiveMessageFromAsync”。
现在你有一个 RemoteEndPoint.Address 和 Port :-)。
归档时间: |
|
查看次数: |
957 次 |
最近记录: |