tcp - 在 Windows 下的非阻塞 TCP 套接字上使用 SO_SNDBUF 的奇怪行为

标签 tcp buffer send nonblocking

我试图降低我的非阻塞 TCP 套接字上的发送缓冲区大小,以便我可以正确显示上传进度条,但我看到了一些奇怪的行为。

我正在创建一个非阻塞的 TCP 套接字,将 SO_SNDBUF 设置为 1024,验证设置是否正确,然后连接(在调用连接之前和之后都试过了,没有区别)。

问题是,当我的应用程序实际出现并调用发送(发送大约 2MB)而不是返回发送了大约 1024 个字节时,发送调用显然接受了所有数据并返回了 2MB 的发送值(正是我通过了)。一切都正常运行(这是一个 HTTP PUT,我得到了一个响应,等等)但是我最终在我的进度条中显示的是上传在 100% 大约 30 秒然后响应进来。

我已经确认,如果我在收到响应之前停止,则上传不会完成,所以它不像是上传得非常快然后服务器停滞了……有什么想法吗? Windows 甚至会查看此设置吗?

最佳答案

Windows 确实查看了此设置,但该设置未按您预期的那样工作。 当您设置这些缓冲区的大小时,您实际上是在设置您正在与之通信的实际 NIC 上的缓冲区大小,从而确定要发送的数据包的大小。

关于 Windows,您需要了解的是,在您的调用代码和实际 NIC 之间有一个缓冲区,我不确定您是否可以控制它的大小。如果当您在套接字上调用发送操作时,您正在将数据转储到该套接字中,Windows 内核将使用缓冲区中的数据在 NIC 上执行小的逐步发送操作。

这意味着代码实际上会报告 2MB beeing 'sent',但这只是意味着你的 2MB 数据已成功写入内部缓冲区,并不意味着/保证数据已经发送。

我一直致力于视频流和 tcp 通信的类似项目,这些信息可以在 MSDN 论坛和 technet 的某个地方找到,但它需要对它的实际工作原理进行非常详细的搜索。

关于tcp - 在 Windows 下的非阻塞 TCP 套接字上使用 SO_SNDBUF 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5313239/

相关文章:

c++ - socket接收到大数据后recv()返回0

C++ win客户端发送linux服务器变量

networking - IM 应用程序如何设法让用户在不同 LAN 之间传输文件

android - 发送一个字符串到wifi连接的设备在android中返回EHOSTUNREACH(没有到主机的路由)

java - SocketException 连接重置

c++ - DirectX 11:创建多个对象

c# - 无法在 Azure 虚拟机上打开 TCP channel

c - 如何用同一个缓冲区写入两个不同的地方? (C-系统调用)

C 缓冲区溢出 - 输入多少字节

php - 如何使用 jQuery 制作发布数据的按钮