【发布时间】:2013-08-18 17:09:43
【问题描述】:
与这里的许多其他人一样,我正在尝试创建一个网络库。需求基本上是这样的:
- 异步工作并为实时应用程序做好准备(我想到了 FPS 游戏)
- 使用 UDP 并根据需要在顶部设置一个瘦协议层
- 原生使用 IPv6
- 支持多个平台(阅读:我想要 Mono 支持!)
现在在阅读了一些关于如何做到这一点(最鼓舞人心的是Gaffer on Games)之后,我设置了我的开发环境,思考了如何做到这一点,并想出了这个基本的工作流程:
- 初始化一个套接字并告诉它使用“UDPv6”
- 将该套接字绑定到一个端口并使异常不会打扰用户。有一个“绑定”属性告诉他套接字设置正确。
- 了解本地计算机上的 NIC 支持的最大 MTU。
- 初始化多个 SocketAsyncEventArgs,告诉其 Completed 事件调用私有调度方法,并将其缓冲区设置为步骤 3 中最大 MTU 的大小。
- 使用第一个 SAEA 对象调用 Sockets ReceiveFromAsync 方法。
当数据进来时,我会做以下事情:
- 使用下一个空闲 SAEA 对象调用 ReceiveFromAsync 方法
- 从当前 SAEA 对象中获取缓冲区和 Sender 信息并使其再次可用
- 使用收到的消息触发一个新事件。
我对这种方法做了一些测试,效果很好。我每 10 毫秒向它发送一条消息,其中包含 200 个字节的数据,持续 10000 个周期,CPU 或内存负载几乎没有增加。只有网卡负载在增加。但是我想出了一些问题|问题:
- 当我处置我的 PeerSocket 类(即持有套接字)时,我处置每个 SAEA 对象。但由于其中至少有一个仍在侦听新消息,因此会引发 ObjectDisposedException。有没有办法让它停止听?
- MTU 可能会因与其他对等方的方式不同而有所不同,也许每个 SAEA 对象的缓冲区应使用不同的指标来确定缓冲区大小?
- 我还不确定如何处理碎片化的数据报。我将继续将“可靠性标头”写入要发送的数据报中,但是如果数据报被拆分,我不知道此标头信息,对吧?
该库有望在某一天对其他人有用,并且它的存储库是公开可用的。截至本题,当前提交可以在here
找到【问题讨论】:
-
你有什么问题?
-
我所有的问题都是问题,我认为这已经说清楚了。
标签: c# asynchronous .net-4.0 udp socketasynceventargs