繁体   English   中英

select()始终返回0

[英]select() always returns 0

我似乎有select的问题。

while(!sendqueue.empty())
{                                   
  if(!atms_connection.connected)
  {
    //print error message
    goto RECONNECT;
  }

  //select new
  FD_ZERO(&wfds);
  FD_SET(atms_connection.socket, &wfds);

  tv.tv_sec = 1;
  tv.tv_usec = 0;

  retval = select(atms_connection.socket + 1, NULL, &wfds, NULL, &tv);

  if (retval == -1) {
    printf("Select failed\n");                      
    break;
  }                     
  else if (retval) {
    printf("Sent a Message.\n"); 
  }
  else {
    //printf("retval value is %d\n",retval);
    printf("Server buffer is full, try again...\n");                        
    break;
  }
  n = write(atms_connection.socket, sendqueue.front().c_str(), sendqueue.front().length());
}

该函数属于一个线程,当它获取锁时,使用select()清除队列并在循环中写入套接字直到队列为空。

第一次线程获得锁定时, select()很好,但是第二次获取锁定并进入while时它总是返回0。

为了记录,它曾经很好地工作了一段时间,从那以后我没有改变那些代码。

超时时选择返回0。 以下行指定超时为1秒。

tv.tv_sec = 1;

通常,套接字已准备好进行写入,而select将立即返回。 但是,如果套接字输出缓冲区中没有空间用于新数据,则select不会将此套接字标记为准备写入。

例如,当连接的另一端未调用recv/read时,可能会发生这种情况。 未确认数据的数量增加,缓冲区最终变满。 由于超时相当小,因此select经常返回值为0。

除了已经提到的内容之外,选择api本身只会告诉描述符是否准备就绪。 它可以用于读取或写入,具体取决于所选择的操作。

在您的情况下,“发送的消息”打印似乎给出了实际写入数据的错觉,但事实并非如此。 您必须对描述符进行写入调用,该描述符将从select返回为ready。

Select不会神奇地读取或写入缓冲区。 如果您是侦听服务器,则在选择调用成功返回后调用accept或read。 如果您是客户端并且打算编写(就像在您的情况下出现的那样),您需要进行显式的write()或send()调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM