【问题标题】:async tcp socket and progress when sending data发送数据时的异步 tcp 套接字和进度
【发布时间】:2014-06-08 21:36:33
【问题描述】:

我在我的 c++ 代码中使用基于 http 的文件上传(在 linux/android 上运行)。我使用异步 tcp 套接字来写入文件数据。我的问题是我的进度条反映了已写入套接字的内容,而不是实际发送的内容。对于慢速链接,问题变得很明显,在 100% 发送进度通知和发送完整消息之间需要数十秒(有时超过一分钟)。

我不修改 SO_SNDBUF,在我的情况下它是 35KB(由 getsockopt 查询)。如何修复进度通知以正确反映当前传输状态?有没有办法查询仍然保留在缓冲区中的数据大小?有没有办法获取有关传输进度的 TCP 通知(由远程套接字确认)?

【问题讨论】:

  • 您是否考虑过使用诸如libcurl 之类的HTTP 客户端库?如果不是,为什么?
  • @BasileStarynkevitch 它是包含所有代码等等的大型代码库的一部分。采用其他所有完成这项工作的库是不切实际的
  • 是否可以从代码中使用 netstat 实用程序并查看 SO_SNDBUF 是如何被填充的?如果内容字节不断增加,您的传输率就会受到影响。只是一个想法。

标签: c++ linux asynchronous tcp asyncfileupload


【解决方案1】:

您将无法知道此缓冲区的当前大小,因为它位于内核域中,并且没有已知/记录的 ioctl 来告知其大小。即使你知道它,它也根本不便携,因此我认为这不是解决这个问题的好方法。

您可以:

  • 估计整个传输过程中的数据速率,以便在最后计算此 SO_SNDBUF 缓冲区的剩余时间

  • 使用第三方库,其中将包含之前的计算!

编辑:在TCP/IP Architecture, Design & Implementation in Linux 一书中进行了一些研究后,我看到了用于 TCP 套接字监视的NETLINK_TCPDIAG 选项。 Netlink 套接字是内核和用户空间之间的一种 IPC 方法。对于NETLINK_TCPDIAG 选项,很遗憾,没有详细说明……我只知道您必须像这样创建一个套接字:int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TCPDIAG) 并且创建原始套接字需要root 权限。

在那之后,你唯一的朋友似乎是linux/net/ipv4/tcp_diag.c (http://www.cs.fsu.edu/~baker/devices/lxr/http/ident?v=2.6.11.8;i=NETLINK_TCPDIAG)...Google 上没有关于这种协议的任何内容...祝你好运!

【讨论】:

  • 这就是我从实验中看到的。问题在于,由于极慢的移动链接可以随机更改发送缓冲的最后 20K 可能需要任何随机时间量。就我而言,我有一个错误报告,花了将近一分钟。我认为应该有一种方法可以从 TCP 堆栈获取有关远程接收状态的通知。 TCP 堆栈在内部进行所有检查,我不明白为什么无法通知用户态代码有关 tcp 进度的信息。
  • 因为我发现了一些关于 TCP 监控的信息,所以我编辑了我的回复 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 2013-09-16
  • 1970-01-01
  • 1970-01-01
  • 2014-07-25
  • 1970-01-01
相关资源
最近更新 更多