这是关于在Windows上开发的TCP服务器。服务器将连接数千个客户端。服务器将继续以非阻塞异步方式向客户端发送随机大小的字节(可以说1到64KB之间的任何内容)。
目前,在致电WSASend
之前,我没有任何约束或条件。我只是使用任何大小的缓冲区调用它,并在发送数据后接收回调(因为它是非阻塞调用)。
问题是,如果一个或几个客户端接收数据的速度很慢,最终我的服务器的内核缓冲区会变满,最后我会收到缓冲区溢出(WSAENOBUFS
)错误。
为避免这种情况,我打算这样做:
如果服务器有(X)大小的内核缓冲区,并且如果连接的最大客户端数是(N)那么我只允许在每个客户端的套接字上写入(X)/(N)字节。 (因此,对于50K连接和内核缓冲区大小为128 MB,我每次只向每个套接字写入最多2684个字节)并且一旦我收到回调,我就可以发送下一组字节。 这种方式即使任何或少数客户端都很慢,也不会导致占用所有内核缓冲区及其待处理数据。
现在问题是:
答案 0 :(得分:5)
在同一个套接字上没有多个WSASend()
个未完成的调用。为传出数据维护自己的缓冲区。将数据放入缓冲区时,如果缓冲区先前为空,则将当前缓冲区内容传递给WSASend()
。每次WSASend()
完成时,它会告诉您它发送了多少字节,因此从缓冲区前面删除那么多字节,如果缓冲区不为空,则再次使用剩余内容再次调用WSASend()
。虽然WSASend()
正忙,但如果您需要发送更多数据,只需将其附加到缓冲区的末尾,让WSASend()
在准备就绪时看到它。
答案 1 :(得分:-1)
让错误告诉你。这就是它的用途。只需继续发送直到出现错误,然后停止。