簡體   English   中英

找出 AF_UNIX + SOCK_SEQPACKET 最大消息大小

[英]find out AF_UNIX + SOCK_SEQPACKET maximum message size

我想知道是否有可能找出除實驗之外的SEQPACKET的最大長度(a-la for( i=0; i<100...00; i++ ) send( ... ); )。

而且,第二個問題:

如果我收到errno == EMSGSIZE試圖發送AF_UNIX SEQPACKET ,是否可以保證是因為最大消息大小,還是有其他原因?

限制來自變量sysctl_wmem_default 它可以在 proc 文件系統中查看: /proc/sys/net/core/wmem_max

在這一點上,不同的 Linux 版本可能有不同的實現。 但是對於 UNIX 域套接字有這種代碼:

sk->sk_sndbuf = sysctl_wmem_default;

err = -EMSGSIZE;
if (len > sk->sk_sndbuf - 32)
    goto out;

所以實際限制是: /proc/sys/net/core/wmem_max 的值減去 32 我不知道這個幻數在版本之間變化了多少。 /proc/sys/net/core/wmem_max 的值似乎因可用內存頁面而異。

在我的 linux 框中,該值是 105472。最大數據報大小(當使用 AF_UNIX 和 SOCK_DGRAM 時)是 105440。如果我嘗試發送大小為 105441 的消息,它將因 EMSGSIZE 而失敗。

打開套接字后,您可以使用以下代碼進行檢查:

int s = socket(AF_UNIX, SOCK_DGRAM, 0); // or SOCK_SEQPACKET
int dgram_max_size = 0;
socklen_t optlen = sizeof(dgram_max_size);
int r = getsockopt(s, SOL_SOCKET, SO_SNDBUF, &dgram_max_size, &optlen);
if(r != 0) {
    printf("error: can't retrieve socket max. size\n");
    exit(1);
}

對於任何套接字,都必須在發送數據之前完成,以確保大小為最大值。 對於數據報套接字,它可能隨時都可以工作。 對於基於流的套接字,緩沖區可能會在您寫入時縮小並隨着數據發送而增長。

注意:正如 SKi 所提到的,大小可能會偏離幾個字節 32 可能是數據包頭。 因此,您的數據包數據可能僅限於dgram_max_size - 32

暫無
暫無

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

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