EWOULDBLOCK:
用于非阻塞模式,不需要重新读或者写
EINTR:
指操作被中断唤醒,需要重新读/写
在Linux环境下开发经常会碰到很多错误(设置errno),其中EAGAIN是其中比较常见的一个错误(比如用在非阻塞操作中)。
从字面上来看,是提示再试一次。这个错误经常出现在当应用程序进行一些非阻塞(non-blocking)操作(对文件或socket)的时候。
例如,以 O_NONBLOCK的标志打开文件/socket/FIFO,如果你连续做read操作而没有数据可读。此时程序不会阻塞起来等待数据准备就绪返 回,
read函数会返回一个错误EAGAIN,提示你的应用程序现在没有数据可读请稍后再试。
又例如,当一个系统调用(比如fork)因为没有足够的资源(比如虚拟内存)而执行失败,返回EAGAIN提示其再调用一次(也许下次就能成功)。
EAGAIN:
Linux - 非阻塞socket编程处理EAGAIN错误
在linux进行非阻塞的socket接收数据时经常出现Resource temporarily unavailable,errno代码为11(EAGAIN),这是什么意思?
这表明你在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏socket的同步,不用管它,下次循环接着recv就可以。
对非阻塞socket而言,EAGAIN不是一种错误。在VxWorks和Windows上,EAGAIN的名字叫做EWOULDBLOCK。
另外,如果出现EINTR即errno为4,错误描述Interrupted system call,操作也应该继续。
最后,如果recv的返回值为0,那表明连接已经断开,我们的接收操作也应该结束。
关于 errno ==EINTR 的小结
如果read()读到数据为0,那么就表示文件读完了,如果在读的过程中遇到了中断则read()应该返回-1,同时置errno为EINTR。
因此判断read的条件如下:
if <=0
{
if==0
{
表示文件结束, 处理
}
if(<0 && errno==EINTR)
{
表示中断,处理
{
否则,出错
}
如果 write()返回0,那么就表示出错,也就是无法写入了;而如果在写的过程中遇到了中断,那么write()会返回-1,同时置errno为EINTR。
因此判断write的条件如下:
if<=0
{
if<0
{
if errno==EINTR
那么重试
else
错误处理
}
if ==0
break;
}
ssize_t readn ( int fd, void *vptr, size_t n )
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr=vptr;
nleft=n;
while ( nleft>0 )
{
if ( ( nread = read ( fd,ptr,nleft ) ) < 0 )
{
if ( errno == EINTR )
nread = 0;
else
return ( -1 );
}
nleft-=nread;
ptr+=nread;
}
return ( n-nleft );
}
ssize_t writen ( int fd, const void *ptr, size_t n )
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr=vptr;
nleft=n;
while ( nleft>0 )
{
if( ( nwritten=write( fd, ptr, nleft ) )<=0 )
{
if( nwritten<0 && errno == EINTR )
nwritten = 0;
else
return (-1);
}
nleft-=nwritten;
ptr+=nwritten;
}
return (n);
}
写函数write
ssize_t write(int fd,const void *buf,size_t nbytes)
write函数将buf中的nbytes字节内容写入文件描述符fd。成功时返回写的字节数,失败时返回-1,并设置errno变量。
在网络程序中,当我们向套接字文件描述符写时有俩种可能:
1) write的返回值大于0,表示写了部分或者是全部的数据;
2) 返回的值小于0,此时出现了错误,我们要根据错误类型来处理。
如果错误为EINTR表示在写的时候出现了中断错误。如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接)。
读函数read
ssize_t read(int fd,void *buf,size_t nbyte)
read函数是负责从fd中读取内容。当读成功时,read返回实际所读的字节数。如果返回的值是0,表示已经读到文件的结束了。小于0表示出现了错误。如果错误为EINTR说明读是由中断引起的,如果是ECONNREST表示网络连接出了问题。
EWOULDBLOCK:用于非阻塞模式,不需要重新读或者写EINTR:指操作被中断唤醒,需要重新读/写 在Linux环境下开发经常会碰到很多错误(设置errno),其中EAGAIN是其中比较常见的一个错误(比如用在非阻塞操作中)。从字面上来看,是提示再试一次。这个错误经常出现在当应用程序进行一些非阻塞(non-blocking)操作(对文件或socket)的时候。
EAGAIN
和
EWOULD
BLOCK
是linux环境下的两个错误码,在
非阻塞
IO中经常会碰到,对新手而言,如何处理这两个值非常头疼。如果处理不当,很容易导致程序异常。
EAGAIN
的官方定义:
“Resource temporarily unavailable.” The call might
该工具通过模拟glibc通过LD_PRELOAD技术公开的轮询和读/写syscall来模拟理想的慢速网络。
通过将此动态库预加载到您的网络服务器进程,它将拦截“ poll”,“ close”,“ send”和“ writev”系统调用,仅允许写入的系统调用一次实际写入单个字节(不刷新) ),并返回
EAGAIN
,直到在当前套接字fd上调用的另一个“轮询”为止。
同样,可以配置该库以拦截C级的“ read”,“ recv”,“ recvfrom”调用,以模拟同时进行或不进行慢速写入的极慢的读取操作。
必须首先通过“轮询”调用来调用套接字fd,以将该工具自身标记为“活动fd”,并触发写入系统调用的子序列以表现不同。
使用此工具,甚至可以在本地(使用环回设备)模拟极端网络条件。
该工具旨在替代旧的良好工具。
只需发出以下命令来构建文件mockagain.so
这两个在linux下表示同一个意思,在
非阻塞
模式下,表示当前暂无数据可读。
参考:https://www.dyxmq.cn/program/code/c-cpp/how-to-handle-eagin-and-
ewould
block
-error-in-linux-c.html
这些改进旨在使不同平台和环境之间的行为规范化,并使文件系统访问对错误的恢复更具弹性。
将open和readdir调用排队,如果文件描述符过多而导致EMFILE错误,则在关闭文件后重试它们。
修复了lchmod适用于0.6.2之前的Node版本。
如果可能,实现fs.lutimes 。 否则,它会变成noop。
如果用户不是root用户,则忽略chown , fchown或lchown EINVAL和EPERM错误。
如果不可用,则使lchmod和lchown成为noop。
如果read导致
EAGAIN
错误,则重试读取文件。
在Windows上,如果发生EACCESS或EPERM错误,它会重试文件重命名最长一秒钟,这可能是因为防病毒软件已锁定目录。
// use just like fs
在某些套接字的函数操作不能立即完成时,会出现错误码
EWOULD
BLOCK
和
EAGAIN
Linux E
INT
R错误码
在类UNIX/Linux中调用一些socket函数时(connect,send,recv,epoll_wait等),除了在函数调用出错时会返回-1,这些函数可能被信号中断时也会返回-1,此时我们可以通过错误码errno判断是不是E
INT
R,来确定是不是被信号中断。如果是,则说明被信号中断,我们需要再次调用该函数进行重试。
bool SendData(const
在Linux环境下开发经常会碰到很多错误(设置errno),其中
EAGAIN
是其中比较常见的一个错误(比如用在
非阻塞
操作中)。在man手册关于read的解释如下:
RETURN VALUE
On success, the number of bytes read is returned(zero indicates end of file), and the file position is advanced by this number. It is not an error if thi
提供封装核心POSIX接口的轻量级C ++ 11抽象。
针对Linux 3.x +,FreeBSD 9.x +和Mac OS X 10.7+(按此顺序)。
除了系统的C ++标准库外,没有运行时依赖项。
除了Autotools工具链和C ++ 11编译器之外,没有构建先决条件。
与Clang和GCC或任何标准C ++ 11实现兼容。
100%免费且不受阻碍的软件,可在任何情况下以任何目的使用。
提供零成本的抽象包装文件描述符。
确保使用O_CLOEXEC打开O_CLOEXEC 。
缓解POSIX接口带来的各种竞争条件。
封装E
INT
R和
EAGAIN
错误处理。
区分逻辑错误,运行时错误和致命错误。
尽可能避免传递POSIX标头。
Caveat utilitor :将来,该项目的顶级posi
《 Netty基础与源码分析》持续更新中...
本文结合了《 Netty权威指南》的一些知识点。
纸上得来终觉浅,源代码部分来自于自己对源码的解读,并加上一些主流开源框架对Netty使用的实践。
一,Linux网络I / O模型
1,双重I / O模型
在进程空间中调用recvfrom,系统调用直到数据包到达被复制到应用进程堆栈中或发生错误才返回,整个过程会一直等待。
2,非双向I / O模型
recvfrom从应用层到内核的时候,如果该长度没有数据,直接返回
EWOULD
BLOCK
错误,则检查该状态,看是不是有数据到来。
3,输入/输出模型
Linux提供选择/轮询,进行通过一个或多个fd传递给选择或轮询系统调用,分开在选择操作上。
Linux提供的另一个epoll系统调用使用基于事件驱动方式代替顺序扫描,因此性能更高。
4,信号驱动I / O模型
开启套接口信号驱动I / O功能,通过
使用前记得连上学校wifi
关闭屏幕后断网了,去系统设置里给APP开锁屏清理白名单;默认在登陆后有通知栏提示,如果没有,也是系统设置没交保护费,自行设置去,通知栏的存在是为了,且方便用户看。
广财版去掉了 keep40_extra 包的发送,不影响使用,其他学校看着办,一般也不用。
已知 Bug
偶发性异常 recvfrom failed:
EAGAIN
(Try again) 可能为UDP丢包,目前解决方案是重发数据包。
偶发性异常 sendto: Operation not Permitted google说是Linux(android也是linu
这个条件判断通常用于检查
非阻塞
I/O 操作返回的错误码。当 errno 的值为
EAGAIN
或者
EWOULD
BLOCK
时,表示当前操作被阻塞,但是可以稍后再次尝试。
EAGAIN
和
EWOULD
BLOCK
的值通常是相等的,它们表示的含义也是一样的。在
非阻塞
模式下,如果操作无法立即完成(例如读取或写入操作),系统会返回这两个错误码之一,以告知调用者稍后再试。
因此,这个条件判断可以用来判断当前操作是否被阻塞,如果是,则可以进行一些额外的处理(例如等待一段时间后再次尝试),或者将操作放入等待队列中。