[英]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.