еквивалент на TIOCOUTQ / SIOCOUTQ в Windows

Досега моето търсене в Google и излизане от msdn предполага, че Microsoft Windows не предлага никакъв еквивалент на TIOCOUTQ / SIOCOUTQ за намиране на количеството неизпратени данни в буфера за изпращане на сокета. Ще бъде толкова полезно, ако някой добър хак открие нещо друго и може да го публикува тук. Това ще позволи на следния ми код да стане междуплатформен

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;
}

person mdk    schedule 16.10.2012    source източник
comment
Свързани: stackoverflow.com/q/12858259   -  person icktoofay    schedule 23.12.2012
comment
може би това може да помогне: stackoverflow.com/a/40207176 цитиране: GetPerTcpConnectionEStats с опцията TcpConnectionEstatsSendBuff ви дава както неизпратени, така и изпратени данни -not-ACK-ed данни като две отделни числа   -  person NorbertM    schedule 22.01.2021


Отговори (2)


Доколкото знам, в Windows няма такова извикване. (Жалко, тъй като работи много добре!)

Следната връзка обаче намирам за изключително полезна и може да ви помогне да разрешите проблема си. Концепциите са за всяка операционна система, освен очевидно частта SIOCOUTQ, спомената в раздела "Какво друго може да се направи?".

Най-добрата страница so_linger или защо моят tcp не е надежден

person hookenz    schedule 18.01.2013
comment
За информация, тази функция depleteSendBuffer в SIOCOUTQ примерен код, посочен в тази статия, е изключително лоша и очевидно ще блокира, ако отдалеченото прекъсне връзката преди ACK на всички данни, като по този начин предотвратява достигането на 0 на вашата SIOCOUTQ стойност. - person Pavel P; 24.07.2017

Добавяйки коментара на Павел П, мога да потвърдя, че е блокиран. Поправка за функцията depleteSendBuffer (линукс версия):

/*!\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 ;
}
person Gull_Code    schedule 21.11.2020