0

I use http based file upload in my c++ code (runs on linux/android). I use async tcp socket for writing file data. My issue is that my progress bar reflects what have been written to the socket, not what was actually sent out on the wire. Problem becomes obvious with slow links where it takes tens of seconds (sometimes over a minute) between 100% sent progress notification and send complete message.

I don't modify SO_SNDBUF, in my case it's 35KB (queried by getsockopt). How can I fix progress notification to correctly reflect current transfer status? Is there a way to query size of data that's still remains in the buffer? Is there a way to get TCP notification about transfer progress (as confirmed by remote socket)?

Pavel P
  • 15,789
  • 11
  • 79
  • 128
  • Did you consider using some HTTP client library like [libcurl](http://curl.haxx.se/libcurl/)? If not, why? – Basile Starynkevitch Apr 23 '14 at 20:50
  • @BasileStarynkevitch it's part of large code base that contains all that code and much more. It's just not practical to take every other lib that does the job – Pavel P Apr 24 '14 at 02:50
  • Is it possible to use netstat utility from code and see how SO_SNDBUF is being filled up? If the content bytes keeps increasing your transfer rate is suffering.Just a thought. – Prabhu Apr 24 '14 at 06:06

1 Answers1

0

You won't be able to know the current size of this buffer, because it is in kernel land and there is no known / documented ioctl to tell its size. Even you could know it, it won't be portable at all, thus I don't think it is a good way to solve this problem.

You can either:

  • Estimate the data rate during the whole transfer, in order to calculate, at the end, the time remaining for the buffer of thise SO_SNDBUF

  • Use a third party library, which will include the previous computation !

EDIT: After some research in the book TCP/IP Architecture, Design & Implementation in Linux, I've seen the NETLINK_TCPDIAG option for TCP socket monitoring. Netlink sockets is an IPC method between kernel and user land. For the NETLINK_TCPDIAG option, unfortunately, there is no detail ... I just know that you must create a socket like this: int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TCPDIAG) and raw socket creation needs root privileges.

After that, your only friend seems to be linux/net/ipv4/tcp_diag.c (http://www.cs.fsu.edu/~baker/devices/lxr/http/ident?v=2.6.11.8;i=NETLINK_TCPDIAG)... There is nothing on Google about this type of protocol ... Good luck !

AntiClimacus
  • 1,380
  • 7
  • 22
  • That's what I see from my experiments. The problem is that because of extremely slow mobile links that can randomly change sending last 20K that were buffered could take any random amount of time. In my case I had a bug report where it took almost a minute. I thought there should be a way to get notification from TCP stack about remote receive state. TCP stack does all the checking internally and I don't understand why it's not possible to notify userland code about tcp progress. – Pavel P Apr 24 '14 at 02:54
  • As I've found something about TCP monitoring, I've edited my response ;) – AntiClimacus Apr 24 '14 at 23:53