【问题标题】:Behavior of SO_SNDBUF when using socketpair使用 socketpair 时 SO_SNDBUF 的行为
【发布时间】:2016-09-14 10:30:18
【问题描述】:

我想使用 socketpair 在两个线程之间发送消息。 我正在编写代码来找出可以使用套接字对发送多少条消息,消息大小为 16 字节(两个指针)。我使用的代码如下:

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 中发送消息时是否使用了固定大小的标头?

【问题讨论】:

    标签: c++ c socketpair


    【解决方案1】:

    似乎类似于:AF_UNIX socket overhead?

    达到的限制应该是net.unix.max_dgram_qlen:要排队的最大数据报数。

    读取实际值:

    sysctl net.unix.max_dgram_qlen
    

    设置新值:

    sysctl net.unix.max_dgram_qlen=...
    

    【讨论】:

    • 我系统中net.unix.max_dgram_qlen的值设置为10。另外,这个参数只适用于Datagram Sockets,而这里使用的是Stream Sockets。在link 的讨论中讨论了内核为簿记保留空间,因此从getsockopt(readFD, SOL_SOCKET, SO_SNDBUF, &amp;rSndBuff, &amp;optlen); 收到的 sndbuf 值将是实际值的两倍。考虑到这一点,我在计算中将 sndbuf 减半。仍然不能解释消耗的额外缓冲区空间。
    猜你喜欢
    • 1970-01-01
    • 2014-02-28
    • 2011-07-15
    • 1970-01-01
    • 2012-07-12
    • 2021-01-20
    • 1970-01-01
    • 2015-04-25
    • 2017-11-03
    相关资源
    最近更新 更多