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()。它就在那里,我只是没有发表它,因为它不是问题。但是谢谢:-)