转载: https://blog.csdn.net/wm_1991/article/details/51858997

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表示网络连接出了问题。

原文链接: https://blog.csdn.net/wm_1991/article/details/51858997 1. 驱动使用down_ int erruptible,并在该函数返回非零 时返回-E INT R;应用程序不处理signal,使用CTRL-C退出应用程序:     驱动从down_ int erruptible返回,应用程序Terminate。 2. 驱动使用down_ int erruptible,并在该函数返回非零 时返回-ERESTARTSYS;应用程序不处理signal,使用CTRL-C退出应用程... 当程序在执行处于阻塞状态的系统调用时接收到信号,并且我们为该信号设置了信号处理函数,在信号处理函数返回后,程序将面临继续执行或不执行慢速系统调用两种选择,默认情况下是系统调用将被中断,并且errno被设置为E INT R。我们可以选择继续执行,有以下两种方法: 1.在设置信号处理函数的时候,为信号设置SA_RESTART标志以自动重启被该信号中断的系统调用,但是该方法对某些慢速系统调用无效,比如epoll_wait,poll,seletc等慢速系统调用,即使给信号设置了该选项,也会被中断。具体对那些慢速系统调用 1、什么是慢系统调用? 该术语适用于那些可能永远阻塞的系统调用。永远阻塞的系统调用是指调用永远无法返回,多数网络支持函数都属于这一类。如:若没有客户连接到服务器上,那么服务器的accept调用就会永远阻塞。 在《UNIX Networking programming》Chapte5中论述了“slow system call"的概念, 而且给出了E INT R的处理方法。 慢系统调用(slow system call):此术语适用于那些可能永远阻塞的系统调用。永远阻塞的系统调用是指调用有可能永远无法返回,多数网络支持函数都属于这一类。如:若没有客户连接到服务器上,那么服务器的accept调用就没有返回的保 在linux的socket编程中,经常要处理E INT R错误,其 为4,用strerror(errno)调用返回的错误描述为: Int erruptedsystem call. 这里给出一个connect连接中对E INT R处理的网址:另外转载网络上其他兄弟对E INT R错误的处理:1.accetp()是慢系统调用,在信号产生时会中断其调用并将errno变量设置为E INT R,此时应重新调用accept()。... socket编程里面的通过send和recv实现客户端服务器的交互 tcp 里面的read和write则是对发送的数据进行读,和写入将要发送的数据 http://blog.csdn.net/u011408355/article/details/45921541 上面的博客记录的很仔细。。。 一旦,我们建立好了tcp连接之后,我们就可以把得到的fd当作文件描述符来使... E INT R: 4 阻塞的操作被取消阻塞的调用打断。如设置了发送接收超时,就会遇到这种错误。 只能针对阻塞模式的socket, 非阻塞 模式不会出现这个错误。读,写阻塞的socket时(recv,send),-1返回,错误号为E INT R,说明在数据传输前接收到一个信号(A signal occurred before any data was transmitted.)。出现这种情况,操作应该继续。如果recv的返回 为0,那表明连接已经断开,接收操作应该结束。 对于s... send/recv write/read 函数返回 大于 0,表示成功发送或成功接收了多少字节,但是发送或者接收的字节数可能是部分字节数,比如你需要发送buf_length长度的数据,但是send/write返回的n有可能 < buf_length,这是因为发送缓冲区可能已经满了。E INT R:当进程在一个慢系统调用中阻塞时,如果捕获到某个信号且相应信号处理函数返回时,这个系统调用不再阻塞而是被中断,就会调用返回错误(一般为-1)并设置 errno 为 E INT R。返回 小于0,需要区分errno。 如果错误为E INT R表示在读/写的时候出现了中断错误 read()如果读到数据为0,那么就表示文件结束了,如果在读的过程中遇到了中断那么会返回-1,同时置errno为E INT R。 或者是write()如果写的过程中遇到中断就会返回-1 并设置errno为E INT R 在 非阻塞 模式下当read读完fd中所有内容后将返回-1,并且errno设置为 EAGAIN read函数说明 read()会把参数fd 所指的文件传送count个字节到buf指针所指的内存中。 若参数count为0,则read为实际读取到的字节数, 如果返回0,表示已到达文件尾或是无可读取的数据 但在O_NON BLOCK 模式下,无数据将返回-1 E INT R 此调用被信号所中断。 /usr/include/errno.h -> /usr/include/x86_64-linux-gnu/bits/errno.h -> /usr/include/linux/errno.h -> /usr/include/x86_64-linux-gnu/asm/errno.h -> /usr/include/asm-generic/errno.h -> /usr/include/asm-generic/errno-base.h 一路跟下去,找到在 /usr/include EAGAIN EWOULD BLOCK 、E INT R与 非阻塞 长连接 EWOULD BLOCK 用于 非阻塞 模式,不需要重新读或者写E INT R指操作被中断唤醒,需要重新读/写在Linux环境下开发经常会碰到很多错误(设置errno),其中 EAGAIN 是其中比较常见的一个错误(比如用在 非阻塞 操作中)。从字面上来看,是提示再试一次。这个错误经常出现在当应用程序进行一些 非阻塞 (non- block ing)操...