6

到目前为止,我在谷歌上搜索和检查 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;
}
4

2 回答 2

1

据我所知,Windows 中没有这样的调用。(可惜效果很好!)

但是,我发现以下链接非常有用,可以帮助您解决问题。这些概念适用于任何操作系统,除了“还有什么可以做的?”中提到的 SIOCOUTQ 部分。部分。

终极so_linger页面或者为什么我的tcp不可靠

于 2013-01-18T04:43:44.290 回答
1

添加 Pavel P 评论,我可以确认它是死锁的。修复 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 ;
}
于 2020-11-21T17:37:37.447 回答