2016-05-18 5 views
3

socketpairを使用して2つのスレッド間でメッセージを送信したいとします。 サイズが16バイト(2つのポインタ)のメッセージで、ソケットペアを使用して送信できるメッセージの数を調べるコードを書いています。私が使用したコードは以下の通りです:socketpairを使用したときのSO_SNDBUFの動作

int fds[2]; 
socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, fds); 

int readFD=fds[0]; 
int writeFD=fds[1]; 
getsockopt(readFD, SOL_SOCKET, SO_SNDBUF, &rSndBuff, &optlen); 
getsockopt(readFD, SOL_SOCKET, SO_RCVBUF, &rRcvBuff, &optlen); 
cout <<"Read FD : Send Buff : "<<rSndBuff<<" Recv Buff : "<<rRcvBuff<<endl; 
getsockopt(writeFD, SOL_SOCKET, SO_SNDBUF , &wSndBuff, &optlen); 
getsockopt(writeFD, SOL_SOCKET, SO_RCVBUF , &wRcvBuff, &optlen); 
cout <<"Write FD : Send Buff : "<<wSndBuff<<" Recv Buff : "<<wRcvBuff<<endl; 

int count=0; 
while (1) 
{ 
    char * im[2]; 
    int sentCount=send(writeFD, im, sizeof(im), MSG_DONTWAIT | MSG_NOSIGNAL); 

    if(sentCount<0) 
    { 
    ioctl (readFD , FIONREAD , &rRcvBuff); 
    cout <<"Size of data sent in one message : "<<sizeof(im)<<endl; 
    cout <<"Recv Buff : "<<rRcvBuff<<endl; 
    cout <<"Sent : " <<sizeof(im)*count<<endl; 
    cout<<"Unable to send : "<< errno<< " "<<strerror(errno)<<endl; 
    cout<<"Count : " <<count<<endl; 
    break; 
    } 
    else if(sentCount!=sizeof(im)) 
    { 
    ioctl (readFD , FIONREAD , &rRcvBuff); 
    cout <<"Recv Buff : "<<rRcvBuff<<endl; 
    cout<<EMSGSIZE<<endl; 
    cout<<"Count : " <<count<<endl; 
    break; 
    } 
    count++; 
} 

スレッド/プロセスがreadFDをリッスンしていません。 writeFD​​の送信バッファがいっぱいになるとwhileループが終了するはずです。

次のような出力が見られます:

Read FD : Send Buff : 129024 Recv Buff : 129024 
Write FD : Send Buff : 129024 Recv Buff : 129024 
Size of data sent in one message : 16 
Recv Buff : 5504 
Sent : 5504 
Unable to send : 11 Resource temporarily unavailable 
Count : 344 

は、私の周り4032であることを送信されたメッセージの数を期待していた(129024 /(2 * 16))。

私はここで何が欠けていますか? AF_LOCALでメッセージを送信する際に固定サイズのヘッダーが使用されていますか?

答えて

1

AF_UNIX socket overhead?と似ています。

制限に達するには、net.unix.max_dgram_qlen:エンキューするデータグラムの最大数を指定してください。私のシステムでnet.unix.max_dgram_qlen` `の値は、このパラメータ、他にも10に設定されている

sysctl net.unix.max_dgram_qlen=... 
+0

:新しい値を設定するには

sysctl net.unix.max_dgram_qlen 

:実際の値を読み取ることが

データグラムソケットにのみ適用されますが、ここではストリームソケットが使用されます。ディスカッション[link](http://stackoverflow.com/questions/10899814/af-unix-socket-overhead)では、カーネルがブックを保管するためのスペースを予約しているので、getsockopt(readFD、 SOL_SOCKET、SO_SNDBUF、&rSndBuff、&optlen);は実際の値の2倍になります。これを考慮して、私は計算でsndbufを半分にしました。それでも、消費される余分なバッファスペースについては説明しません。 –

関連する問題