gpt4 book ai didi

windows - 如何避免异步非阻塞 WSASend 调用的缓冲区溢出

转载 作者:可可西里 更新时间:2023-11-01 02:33:46 27 4
gpt4 key购买 nike

这是关于正在 Windows 上开发的 TCP 服务器。服务器将连接数千个客户端。服务器将持续以非阻塞异步方式向客户端发送随机大小的字节(可以说是 1 到 64KB 之间的任何字节)。

目前我在调用WSASend 之前没有任何约束或条件。我只是用我得到的任何大小的缓冲区调用它,并在发送数据后接收回调(因为它是非阻塞调用)。

问题是,如果一个或几个客户端接收数据的速度很慢,最终我的服务器的内核缓冲区会变满,我最终会收到缓冲区溢出 (WSAENOBUFS) 错误。

为了避免这种情况,我打算这样做:

如果服务器有 (X) 大小的内核缓冲区,并且如果要连接的最大客户端数是 (N),那么我将只允许 (X)/(N) 字节写入每个客户端的套接字。(因此,对于 50K 的连接和 128 MB 的内核缓冲区大小,我将一次最多只向每个套接字写入 2684 个字节)一旦我收到回调,我就可以发送下一组字节。这样,即使任何一个或几个客户端运行缓慢,也不会导致其未决数据占用所有内核缓冲区。

现在的问题是:

  1. 这样做是否正确?

  2. 如果是,多少钱

    一个。内核缓冲区 (X) 的大小,以及

    允许的最大连接数(N),

应该很好地搭配以获得最佳性能。

注意:不是我之前的 question 的副本在同一个问题上。但这更多的是关于验证我在完成答案和 link 后提出的解决方案。我回答了这个问题。

最佳答案

在同一个套接字上不要有多个未完成的 WSASend() 调用。为传出数据维护自己的缓冲区。当您将数据放入缓冲区时,如果缓冲区先前为空,则将当前缓冲区内容传递给 WSASend()。每次 WSASend() 完成时,它都会告诉您它发送了多少字节,因此从缓冲区的前面删除那么多字节,如果缓冲区不为空,则调用 WSASend() 再次使用剩余的内容。当 WSASend() 很忙时,如果您需要发送更多数据,只需将其附加到缓冲区的末尾并让 WSASend() 在准备就绪时查看它。

关于windows - 如何避免异步非阻塞 WSASend 调用的缓冲区溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24867103/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com