Till date my googling and checking out of msdn suggests Microsoft Windows does not offer any equivalent of TIOCOUTQ / SIOCOUTQ to find the amount of unsent data in the socket send buffer. It will be so useful if some good hack discovered something otherwise, and could post it here. It will allow my following code to become cross-platform
int net_get_unsent (const int sockfd, unsigned long &sock_bytes_unsent )
{
/* Queries how much data sent on sockfd,
* may not have yet been recieved by the reciever
*
* returns more than 1 if there's unsent data,
* and fills in the amount of unsent data in sock_bytes_unsent
*
* returns 0 if all the data has been sent
*
* returns < 0 if there was a socket I/O error
* */
int err = 0;
int wsaerr = 0;
if (sockfd <= 0)
return -1;
#ifdef WINDOWS
err = ioctlsocket(sockfd, SIOCOUTQ , &sock_bytes_unsent);
#else
err = ioctl(sockfd, TIOCOUTQ, &sock_bytes_unsent);
#endif
if (err < 0) {
#ifdef WINDOWS
wsaerr = WSAGetLastError();
#else
wsaerr = errno;
#endif
printf("failed to get unsent data error:%d", wsaerr );
sock_bytes_unsent = 0;
return -1 * wsaerr;
} else if (sock_bytes_unsent > 0 ) {
printf( "unsent data: %lu bytes", sock_bytes_unsent );
return 1;
}
return err;
}
As far as I know there isn't such a call in Windows. (A pity since it works very well!)
However, the following link I've found to be extremely useful and may help you solve your problem. The concepts are for any OS except obviously the SIOCOUTQ part mentioned in the "What else can be done?" section.
The ultimate so_linger page or why is my tcp not reliable
Adding on Pavel P comment, I can confirm it is deadlocking. Fix for the depleteSendBuffer func (linux version):
/*!\fn int depleteSendBuffer ( int fd , long timeout )
*\brief wait until the socket is empty or timeout, checking each 50 msec
*\param fd socket descriptor
*\timeout timeout value in msec
*\return TRUE of FALSE
*/
int depleteSendBuffer ( int fd , long timeout )
{
int done = FALSE ;
int lastOutstanding=-1;
timeout /= 50 ;
for( int it = 0 ; it < timeout ; it += 50 )
{
int outstanding;
ioctl(fd, SIOCOUTQ, &outstanding);
if(outstanding != lastOutstanding)
printf("Outstanding: %d\n", outstanding);
lastOutstanding = outstanding;
if(!outstanding)
{
done = TRUE ;
break;
}
usleep( 50000 );
}
return done ;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With