我在Linux上的一个项目使用阻塞套接字。事情是非常连续地发生的,因此非阻塞只会使事情变得更加复杂。无论如何,我发现经常一个recv()
调用返回-1
与errno
设置为EAGAIN
。
该man
页面只真正提到了非阻塞套接字的这种情况,这是有道理的。使用非阻塞,套接字可能会或可能不会,因此您可能需要重试。
是什么原因导致套接字阻塞? 我可以做些什么来避免它?
目前,我要处理的代码看起来像这样(我在出错时抛出了异常,但除此之外,它是一个非常简单的包装器recv()
):
int ret;
do {
ret = ::recv(socket, buf, len, flags | MSG_NOSIGNAL);
} while(ret == -1 && errno == EAGAIN);
if(ret == -1) {
throw socket_error(strerror(errno));
}
return ret;
这是正确的吗? 这种EAGAIN
病很常见。
编辑: 我注意到的一些事情可能是相关的。
我确实使用设置了套接字的读取超时setsockopts()
,但是将其设置为30秒。的EAGAIN
的一次,每30秒的方式更经常发生。 更正 我的调试存在缺陷,EAGAIN
发生的频率不像我想象的那么频繁。也许是超时触发。
对于连接,我希望能够具有连接超时,因此我将套接字临时设置为非阻塞。该代码如下所示:
int error = 0;
fd_set rset;
fd_set wset;
int n;
const SOCKET sock = m_Socket;
// set the socket as nonblocking IO
const int flags = fcntl (sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
errno = 0;
// we connect, but it will return soon
n = ::connect(sock, addr, size_addr);
if(n < 0) {
if (errno != EINPROGRESS) {
return -1;
}
} else if (n == 0) {
goto done;
}
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_SET(sock, &rset);
FD_SET(sock, &wset);
struct timeval tval;
tval.tv_sec = timeout;
tval.tv_usec = 0;
// We "select()" until connect() returns its result or timeout
n = select(sock + 1, &rset, &wset, 0, timeout ? &tval : 0);
if(n == 0) {
errno = ETIMEDOUT;
return -1;
}
if (FD_ISSET(sock, &rset) || FD_ISSET(sock, &wset)) {
socklen_t len = sizeof(error);
if (getsockopt(SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
return -1;
}
} else {
return -1;
}
done:
// We change the socket options back to blocking IO
if (fcntl(sock, F_SETFL, flags) == -1) {
return -1;
}
return 0;
我的想法是将其设置为非阻塞,尝试连接并在套接字上进行选择,以便强制超时。set和restore
fcntl()
调用均成功返回,因此此功能完成后,套接字应再次以阻塞模式结束。
您可能在套接字上设置了非零的接收超时(通过setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,...)
),因为这也会导致recv返回EAGAIN
问题内容: 当我抓取包含使用无头选项产品的页面时,我得到不同的结果。 对于同一个问题,一次我得到未排序的结果,而另一次我得到正确的排序顺序。 Selenium firefox浏览器: 根据这篇文章: “ firefox使用无头选项时不会发送不同的头”。 如何使用无头选项从抓取中获得恒定的结果? 更新: 事实证明,广告弹出窗口隐藏了价格排序菜单。通过设置DebanjanB发布的恒定窗口大小,解决了问
它必须是基本的,但请帮助我理解为什么这不起作用。 当我编写一个普通的arrow函数并返回jsx时,它就工作了。但是,当我使用async/await请求和相同的arrow函数返回jsx时,它失败了。 编辑: 实际上,我必须在列表视图中显示用户的配置文件图像。所以,我调用这个函数来检索我的块中相应用户的图像 这很有效 但事实并非如此
我很难强制S3在它从一个bucket返回的所有对象上设置CORS头,尽管启用了CORS,但由于客户端S3上传正在工作,返回的对象没有CORS头! 我启用的策略是: 对象URL示例https://s3.amazonaws.com/captionable/meme/test 有人知道怎么了吗?
问题内容: 我正在尝试使用PHP从CURL获取响应和响应标头,特别是对于Content- Disposition:因此我可以返回标题中传递的文件名。在curl_getinfo中似乎没有得到返回。 我尝试使用HeaderFunction调用函数以读取其他标头,但是,我无法将内容添加到数组中。 请问有人有什么想法吗? 以下是我的代码的一部分,该代码是Curl包装器类: 问题答案: 在这里,应该这样做:
我想在我的应用程序中显示后退箭头按钮,但当我把这个放在代码中时,应用程序崩溃了: style.xml 类(不是片段):
当我浏览包含使用headless选项的产品的页面时,我会得到不同的结果 对于同一个问题,一次我得到的结果没有排序,另一次得到的结果排序正确。 Selenium firefox浏览器: 根据这篇帖子: “firefox在使用headless选项时不会发送不同的标题”。 如何使用无头选项从刮擦中获得恒定的结果? 更新: 原来,广告弹出窗口隐藏了价格排序菜单。通过设置DebanjanB发布的恒定窗口大小