1

美好的一天!

我正在为一个封闭源代码的游戏开发一个开源服务器 - 游戏使用 TCP/IP 套接字(而不是 UDP,doh ......)所以作为一个基于连接的协议,我被限制使用这个。

我当前的程序结构(简化):

核心线程

  • 接收新连接并创建一个新的客户端对象。

客户对象

  • IOloop(在自己的线程上运行)

    • 从套接字获取数据,处理数据包。(一次一包)
    • 发送从其他线程缓冲的数据(一次一个数据包)

当它是自己的线程时,客户端将立即(无延迟)发送数据。


我注意到程序有一个巨大的缺陷,主要是它发送数据的速度非常慢。因为我是一个包一个包地同步发送数据。(Socket.Send(byte[] 缓冲区))

我想几乎立即发送数据,没有延迟 - 异步。

每次我想发送一个数据包时,我都尝试创建一个新线程(因此每个数据包都在它自己的托管线程上发送),但这是一个巨大的混乱。

我当前的系统使用禁用 nagle 算法的同步发送 - 但这有瓶颈的缺陷 - 发送一个数据包,发送操作块直到 TCP 确认,然后发送下一个......我可以每 100 毫秒轻松发出 10 个数据包,如果数据包需要 400 毫秒才能发送,这会备份并中断。当然,在我的本地主机上,我没有遇到这个问题。


所以,我的问题是:发送多个小数据包的最佳方式是什么?我正在考虑将要在每个 IO 线程循环结束时发送的数据合并到一个大字节缓冲区,以减少来回延迟 - 但这里明显的问题是这破坏了我希望停止的 nagle 算法避免延误。

同步发送如何工作?在我相信的接收方确认正确接收到数据之前,它会阻塞吗?有没有办法可以在不等待确认的情况下做到这一点?我确实理解数据包必须全部按顺序正确(根据协议规范)。

4

1 回答 1

0

我做了一些研究,现在正在使用当前系统:

使用 AsyncCallbacks 的无线程异步发送/接收操作。

所以我让服务器开始一个读取操作,然后回调直到完成,当收到一个数据包时,它被处理,然后一个新的读取操作将开始......

这种方法大大减少了系统开销——线程池、内存等。

我使用了以下一些方法并根据自己的喜好进行了定制:https ://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

非常有效,强烈推荐这种方法。对于任何 TCP/IP 网络应用程序,低延迟非常重要,异步回调是最好的方法。

于 2016-07-08T03:49:15.857 回答