簡體   English   中英

setsockopt()在設置大套接字recv緩沖區時沒有返回錯誤

[英]setsockopt() not returning error when setting a big socket recv buffer

我正在用下面的代碼測試函數setsockopt()並且我得到了一個我不理解的行為:下面是我正在運行的代碼片段( 在Ubuntu 12.04 64bit,Qt 4.8.x上編譯 ):

#include <QCoreApplication>

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <QDebug>

#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int sock = ::socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    int res;
    int bufferSizeByte = QString(argv[1]).toInt();

    qDebug() << "Setting socket buffer size to" << bufferSizeByte << "bytes";
    res = setsockopt( sock, SOL_SOCKET, SO_RCVBUF, (void*)&bufferSizeByte, sizeof(bufferSizeByte) );
    if ( -1 == res )
    {
        qDebug() << "ERROR setting socket buffer size to" << bufferSizeByte << "bytes";
    }

    /*
     *  !! WARNING !!
     *  If we try setting the buff size over the kernel max: we do not get an error
     */

    int readValue = 0;
    unsigned int readLen = sizeof(readValue);
    res = getsockopt( sock, SOL_SOCKET, SO_RCVBUF, (void*)&readValue, &readLen );
    if ( -1 == res )
    {
        qDebug() << "ERROR reading socket buffer size";
    }
    else
    {
        qDebug() << "Read socket buffer size:" << readValue << "bytes";
        Q_ASSERT ( readValue == bufferSizeByte*2 );
    }


    return a.exec();
}

基本上我正在為套接字設置recv緩沖區大小,並將其讀回以驗證操作是否真的成功。 將緩沖區大小設置為使用Linux內核中配置的值( / proc / sys / net / core / rmem_max )將Q_ASSERT()作為expecetd觸發,但我沒有收到setsockopt錯誤消息。

例如:

sergio@netbeast: sudo ./setsockopt 300000 
Setting socket buffer size to 300000 bytes  
Read socket buffer size: 262142 bytes  
ASSERT: "readValue == bufferSizeByte*2" in file ../setsockopt/main.cpp, line 43

我沒有得到的是為什么setsockopt()不會返回錯誤

任何線索?

sock_setsockopt()的實現sock_setsockopt()系統調用setsockopt()最終在內核中調用)有一個注釋,為什么設置太大的值不會導致錯誤。 注釋表明原因是為了與原始BSD實現兼容(因此,為BSD系統編寫的軟件更容易移植到Linux):

            /* Don't error on this BSD doesn't and if you think
             * about it this is right. Otherwise apps have to
             * play 'guess the biggest size' games. RCVBUF/SNDBUF
             * are treated in BSD as hints
             */

請注意,如果在執行此操作時未超過最大大小(並且已滿足最小值),實際存儲的內容是傳遞給SO_RCVBUF的值的兩倍。 手冊頁

SO_RCVBUF以字節為單位設置或獲取最大套接字接收緩沖區。 當使用setsockopt(2)設置時,內核將此值加倍(以便為簿記開銷setsockopt(2)空間setsockopt(2) ,並且getsockopt(2)返回此doubled值。 默認值由/proc/sys/net/core/rmem_default文件設置,最大允許值由/proc/sys/net/core/rmem_max文件設置。 此選項的最小(加倍)值為256。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM