Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ select()始终返回0_C++_Sockets_Select - Fatal编程技术网

C++ select()始终返回0

C++ select()始终返回0,c++,sockets,select,C++,Sockets,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.t

我似乎对
选择有问题

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()
fine,但第二次获得锁并进入,它总是返回0


作为记录,它在一段时间前还可以正常工作,从那时起我就没有更改过该代码。

Selects在超时时返回0。下一行指定超时为1秒

tv.tv_sec = 1;
通常,套接字已准备好写入,select将立即返回。但是,如果套接字输出缓冲区中没有空间容纳新数据,则select不会将此套接字标记为已准备好写入


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

除了前面提到的内容外,select api本身只告诉描述符是否准备就绪。根据所选择的操作,它可用于读取或写入

在您的例子中,“message sent”打印似乎给人一种错觉,即数据实际上是被写入的,而事实并非如此。您必须对从select返回为ready的描述符进行写调用


Select本身不会神奇地读取或写入缓冲区。如果您是侦听服务器,则在select调用成功返回后调用accept或read。如果您是一个客户机并打算进行写入(就像在您的案例中出现的那样),则需要进行显式的write()或send()调用。

返回0,超时过期您的消息“服务器缓冲区已满”是完全错误的。这意味着在超时时间内没有发生任何事情,而不是“服务器缓冲区已满”。如果您没有更改此代码,并且事情停止工作,则可能是您更改的代码有问题。您还应该检查
选择
函数的功能。您要做的是等待一秒钟,看看是否可以不阻塞地编写。它不会检查写入是否成功。事实上,我想知道为什么要使用
select()
发送。只需在阻塞模式下使用
send()
,就可以摆脱整个头痛问题。我将电视秒增加到5秒。但仍然不起作用。你是否建议在select上循环,直到它不是零?我不确定你想实现什么,但我会检查连接的另一端在做什么(应该调用
recv
)。在这种情况下,我只会使用阻塞
send
(没有
select
)。不管怎样,您是否看到连接的另一端正在接收任何内容?我添加了write()。它就在那里,我只是没有发表它,因为它不是问题。但是谢谢:-)