эквивалент 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 cite: GetPerTcpConnectionESTats с опцией TcpConnectionEstatsSendBuff дает вам как неотправленные данные, так и отправленные, но -данные без подтверждения ACK в виде двух отдельных чисел   -  person NorbertM    schedule 22.01.2021


Ответы (2)


Насколько я знаю, в Windows такого вызова нет. (Жаль, так как это работает очень хорошо!)

Тем не менее, следующая ссылка, которую я считаю чрезвычайно полезной, может помочь вам решить вашу проблему. Концепции предназначены для любой ОС, за исключением, очевидно, части SIOCOUTQ, упомянутой в разделе "Что еще можно сделать?".

Идеальная страница so_linger или почему мой tcp ненадежен

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

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

/*!\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