Sokcet网络编程常见异常情况(转)

Sokcet网络编程常见异常情况

版权声明:本文为原博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/huangwei858/article/details/47723613
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/z591826160/article/details/99706473

 

 

 

 

Linux Socket Errno错误代码列表

 124EMEDIUMTYPE   Wrong medium type
   123 ENOMEDIUM    No medium found
   122EDQUOT        Disk quota exceeded
   121 EREMOTEIO    Remote I/O error
   120EISNAM        Is a named type file
   119ENAVAIL       No XENIX semaphores available
   118ENOTNAM       Not a XENIX named type file
   117EUCLEAN       Structure needs cleaning
   116ESTALE        Stale NFS file handle
   115 EINPROGRESS  +Operation nowin progress
   114EALREADY      Operation already in progress
   113 EHOSTUNREACH  No route tohost
   112 EHOSTDOWN    Host is down
   111 ECONNREFUSED  Connection refused
   110 ETIMEDOUT   +Connection timed out
   109 ETOOMANYREFS  Too manyreferences: cannot splice
   108 ESHUTDOWN    Cannot send after transport endpoint shutdown
   107ENOTCONN      Transport endpoint is not connected
   106EISCONN       Transport endpoint is alreadyconnected
   105ENOBUFS       No buffer space available
   104 ECONNRESET   Connection reset by peer
   103 ECONNABORTED  Softwarecaused connection abort
   102 ENETRESET    Network dropped connection on reset
   101 ENETUNREACH   Networkis unreachable
   100ENETDOWN      Network is down
    99 EADDRNOTAVAIL Cannot assignrequested address
    98 EADDRINUSE   Address already in use
    97 EAFNOSUPPORT  Addressfamily not supported by protocol
    96 EPFNOSUPPORT  Protocolfamily not supported
    95 EOPNOTSUPP   Operation not supported
    94 ESOCKTNOSUPPORT Socket typenot supported
    93 EPROTONOSUPPORT Protocol notsupported
    92 ENOPROTOOPT  Protocol not available
    91 EPROTOTYPE   Protocol wrong type for socket
    90EMSGSIZE     +Message too long
    89 EDESTADDRREQ Destination address required
    88ENOTSOCK      Socket operation on non-socket
    87EUSERS        Too many users
    86ESTRPIPE      Streams pipe error
    85 ERESTART     Interrupted system call should be restarted
    84EILSEQ        Invalid or incompletemultibyte or wide character
    83ELIBEXEC      Cannot exec a shared library directly
    82ELIBMAX       Attempting to link in too manyshared libraries
    81 ELIBSCN      .lib section in a.out corrupted
    80ELIBBAD       Accessing a corrupted shared library
    79ELIBACC       Can not access a needed sharedlibrary
    78EREMCHG       Remote address changed
    77EBADFD        File descriptor in bad state
    76ENOTUNIQ      Name not unique on network
    75EOVERFLOW     Value too large for defined data type
    74EBADMSG      +Bad message
    73EDOTDOT       RFS specific error
    72EMULTIHOP     Multihop attempted
    71EPROTO        Protocol error
    70ECOMM         Communication error onsend
    69ESRMNT        Srmount error
    68EADV          Advertise error
    67ENOLINK       Link has been severed
    66EREMOTE       Object is remote
    65ENOPKG        Package not installed
    64ENONET        Machine is not on the network
    63ENOSR         Out of streams resources
    62ETIME         Timer expired
    61ENODATA       No data available
    60ENOSTR        Device not a stream
    59EBFONT        Bad font file format
    57EBADSLT       Invalid slot
    56EBADRQC       Invalid request code
    55ENOANO        No anode
    54EXFULL        Exchange full
    53EBADR         Invalid request descriptor
    52EBADE         Invalid exchange
    51EL2HLT        Level 2 halted
    50ENOCSI        No CSI structure available
    49EUNATCH       Protocol driver not attached
    48ELNRNG        Link number out of range
    47EL3RST        Level 3 reset
    46EL3HLT        Level 3 halted
    45EL2NSYNC      Level 2 not synchronized
    44ECHRNG        Channel number out of range
    43EIDRM         Identifier removed
    42ENOMSG        No message of desired type
    40ELOOP         Too many levels ofsymbolic links
    39 ENOTEMPTY   +Directory not empty
    38 ENOSYS      +Function not implemented
    37ENOLCK       +No locks available
    36 ENAMETOOLONG +File name toolong
    35EDEADLK      +Resource deadlock avoided
    34ERANGE       +Numerical result out of range
    33EDOM         +Numerical argument out ofdomain
    32EPIPE        +Broken pipe
    31EMLINK       +Too many links
    30EROFS        +Read-only file system
    29ESPIPE       +Illegal seek
    28ENOSPC       +No space left on device
    27EFBIG        +File too large
    26ETXTBSY       Text file busy
    25ENOTTY       +Inappropriate ioctl for device
    24EMFILE       +Too many open files
    23ENFILE       +Too many open files in system
    22EINVAL       +Invalid argument
    21EISDIR       +Is a directory
    20ENOTDIR      +Not a directory
    19ENODEV       +No such device
    18EXDEV        +Invalid cross-device link
    17EEXIST       +File exists
    16EBUSY        +Device or resource busy
    15ENOTBLK       Block device required
    14 EFAULT      +Bad address
    13EACCES       +Permission denied
    12ENOMEM       +Cannot allocate memory
    11EAGAIN       +Resource temporarily unavailable
    10ECHILD       +No child processes
     9EBADF        +Bad file descriptor
     8ENOEXEC      +Exec format error
     7E2BIG        +Argument list too long
     6ENXIO        +No such device or address
     5EIO          +Input/output error
     4EINTR        +Interrupted system call
     3ESRCH        +No such process
     2ENOENT       +No such file or directory
     1EPERM        +Operation not permitted
#    0--            Success

错误号

错误

可能的原因

EAGAIN

Try again

在读数据的时候,没有数据在底层缓冲的时候会遇到,一般的处理是循环进行读操作,异步模式还会等待读事件的发生再读

EWOULDBLOCK

Operation would block

在我们的环境中和EAGAIN是一个值, 一般情况下只关心EAGAIN就可以了

EPIPE

Broken pipe

1、接收端关闭(缓冲中没有多余的数据),但是发送端还在write. 2、错误被描述为“brokenpipe”,即“管道破裂”,这种情况一般发生在客户进程不理会(或未及时处理)Socket错误,继续向服务TCP写入更多数据时,内核将向客户进程发送SIGPIPE信号,该信号默认会使进程终止(此时该前台进程未进行coredump)。结合上边的ECONNRESET错误可知,向一个FIN_WAIT2状态的服务TCP(已ACK响应FIN分节)写入数据不成问题,但是写一个已接收了RST的Socket则是一个错误。

ECONNRESET

Connection reset by peer

1、收到RST包可能是接收到数据后不进行读取或者没有读取完毕直接close,另一端再调用write或者read操作,这个时候需要检查一下是否存在脏数据或者一端某些情况下断开的情况. 另外使用了SO_LINGER后close连接,另一端也会收到这个错误. 另外在epoll中一般也是可能返回EPOLLHUP事件。 连接的时候也可能出现这样的错误,这个参考后面的 "listen的时候的backlog有什么影响"中的说明 2、这种情况一般发生在服务进程较客户进程提前终止。当服务进程终止时会向客户TCP发送FIN分节,客户TCP回应ACK,服务TCP将转入FIN_WAIT2状态。此时如果客户进程没有处理该FIN(如阻塞在其它调用上而没有关闭Socket时),则客户TCP将处于CLOSE_WAIT状态。当客户进程再次向FIN_WAIT2状态的服务TCP发送数据时,则服务TCP将立刻响应RST。一般来说,这种情况还可以会引发另外的应用程序异常,客户进程在发送完数据后,往往会等待从网络IO接收数据,很典型的如read或readline调用,此时由于执行时序的原因,如果该调用发生在RST分节收到前执行的话,那么结果是客户进程会得到一个非预期的EOF错误。此时一般会输出“服务器过早终止”错误

EINTR

Interrupted system call

被其他的系统调用中断了, 对于句柄进行操作比较容易出现,一般裸用recv都是需要判断的, 处理也很简单, 再进行一次操作就可以了

ETIMEDOUT

Connection timed out

连接超时, 但是在我们ul_sread_xxx或者ul_swrite_xx系列中也被我们用来表示读写超时

ECONNREFUSED

Connection refused

拒绝连接, 一般在机器存在但是相应的端口上没有数据的时候出现

ENETUNREACH

Network is unreachable

网络不可达,可能是由于路器的限制不能访问,需要检查网络

EADDRNOTAVAIL

Cannot assign requested address

不能分配本地地址,一般在端口不够用的时候会出现,很可能是短连接的TIME_WAIT问题造成

EADDRINUSE

Address already in use

地址已经被使用, 已经有相应的服务程序占用了这个端口, 或者占用端口的程序退出了但没有设置端口复用

ENOTCONN

Transport endpoint is not connected

连接没有链上。 在一个socket出来还没有accept或者connenct, 还有一种情况就是收到对方发送过来的RST包,系统已经确认连接被断

在Unix下进行网络编程时,由于网络并非完全可靠,会遇到各种协议主流程外发生的各种错误。

而健壮的程序必须考虑到这些错误并正确处理,因此这里总结网络编程中可能发生的常见错误。

TCP异常流程

总体

应答超时

​ 在握手,挥手以及消息传递的状态下,若当前发送的报文期待一个应答报文。在规定时间应答报文没有到达,发送方会重发两次报文(报文重发间隔可设置)。若重发三次后依旧没有收到应答,则向应用返回ETIMEOUT

目的不可达

​ 若报文在传送的过程中,因为找不到路由路径,报文无法到达等引发了ICMP错误,发送方会按照上述的方式重发次报文。若重发结束后依旧没有收到应答,则向应用返回EHOSTUNREACH或者ENETUNREACH

禁止分片

​ 在IPV4中,报文超过了MTU长度会导致分片,而其存在DF(Don’t Fragment)标识,表示禁止分片。同时IPV6禁止路由器分片,因此在传送的过程中隐含DF位。在传送过程中设置了DF位而超过了MTU,则会向应用返回EMSGSIZE

阻塞时中断

​ 在系统执行慢系统调用(可能被永远阻塞的系统调用)时阻塞,此时捕获到某个信号并进行了处理(系统对某些信号有默认处理方式),在没有设置自动重启的情况下,会向应用返回EINTR

​ 一般应对EINTR的方式是简单的重新调用,但在connect返回EINTR时不能这么做,因为connect涉及三次握手的过程,需要使用getsockopt获取连接状态

读写时RST

​ 在调用read等阻塞时接收到对端RST信号时,会返回ECONNREST。同时对发送方断开的套接字写时也会返回ECONNRESET

写RST套接字

​ 当进程向收到RST的套接字执行写操作的时候,内核向该进程发送一个SIGPIPE信号,该信号的默认行为是终止进程,因此进程必须捕获它以免不情愿的被终止

​ 不论进程是捕捉了该信号并从信号处理函数中返回,还是简单忽略该信号,写操作都讲返回EPIPE错误

握手部分

首次握手服务端RST

TCP三次握手

​ 在客户端第一次握手时,若服务端返回RST报文,立即向应用返回ECONNREFUSED

握手结束客户端RST

tcp三次握手后RST

​ 在较为繁忙的服务器中,可能出现上图客户端刚经历三次握手后随机发送RST报文的情况,posix指出这种情况errno设置为ECONNABORTED,只需要再次调用accept即可。

​ 而在Berkeley的实现中,返回EPROTO错误,代表协议错误,是一种致命错误,由内核把该连接从已完成连接套接字队列中释放,若再次调用accept,则不会处理到本次请求,可能导致阻塞

数据传送部分

服务端主机崩溃

​ 由于客户端无法收到服务端的任何回应,会重发处理,最终向应用返回的情况可能为应答超时或目的不可达

​ 若想尽快的检测出主机崩溃,不主动发送数据也可做到,即套接字选项的SO_KEEPALIVE(类似心跳机制)

挥手部分

tcp四次挥手

服务端进程终止或关机

​ 服务端由于进程崩溃或者手动kill后,进程终止关闭所有打开的描述符。这导致了其向客户端发送了一个FIN,客户端则响应了一个ack,TCP挥手的前半部分完成,服务端不在发送数据。

​ 但是此时客户端并不知道服务器端已经终止了。当客户端向服务器写数据的时候,由于服务器进程终止,所以响应了RST

​ 这种情况下可以由select或者poll检测到服务端的终止。

  • 如果对端TCP发送数据,套接字可读,并且read返回一个大于0的值(读入字节数)
  • 如果对端TCP发送了FIN(对端进程终止),套接字可读,并且read返回0(EOF)
  • 如果对端TCP发送RST(对端崩溃并重启),套接字可读,并且read返回-1,errno中含有确切错误码

服务端终止后重启

​ 由于重启后已经丢失了套接字连接信息,服务端对客户端的报文响应RST。若此时客户端读,则会返回ECONNRESET

套接字api异常情况

socket

errno含义可能情况致命解决
EACCES权限不足
EAFNOSUPPORT地址族不支持参数错误
EINVAL参数错误未知协议或协议族不可用
EMFILE打开的文件过多进程级打开的fd达上限ulimit -n 调整或等待资源释放
ENFILE打开的文件过多系统级打开的fd达上限等待资源释放
ENOBUFS/ENOMEM内存不足Buffer或文件表无法创建等待资源释放

bind

errno含义可能情况致命解决
EACCES权限不足申请保留端口且非root运行
EADDRINUSE地址已被使用绑定已使用地址或申请临时端口时已占满临时端口已满时重试
EBADFfd不可用fd已关闭或参数非法
EINVAL参数错误套接字重复绑定或参数错误
ENOTSOCK非套接字fd参数错误

listen

errno含义可能情况致命解决
EADDRINUSE地址已被使用监听已监听端口或未bind至确定端口而申请临时端口时已占满临时端口已满时重试
EBADFfd不可用fd已关闭或参数非法
ENOTSOCK非套接字fd参数错误
EOPNOTSUPP操作不支持只支持SOCK_STREAM类套接字(TCP)

accept

errno含义可能情况致命解决
EWOULDBLOCK/EAGAIN资源暂时不可用(非阻塞)队列中无完成握手的连接重试或处理其他事务
EBADFfd不可用fd已关闭或参数非法
ECONNABORTED连接已中断握手结束客户端RST重试或处理其他事务
EFAULT地址错误addr参数没有指向用户可写空间
EINTR调用中断调用被信号中断重试或处理其他事务
EINVAL参数错误套接字未在监听态或addrlen/flags错误
EMFILE打开的文件过多进程级打开的fd达上限ulimit -n 调整或等待资源释放
ENFILE打开的文件过多系统级打开的fd达上限等待资源释放
ENOMEM/ENOBUFS内存不足套接字buffer内存不足而非系统内存不足等待资源释放

connect

errno含义可能情况致命解决
EACCES/EPERM权限不足/操作未允许未设置广播标记但连接广播地址或防火墙禁止连接
EADDRINUSE本地地址已被使用重试,等待资源释放
EADDRNOTAVAIL地址不可用未bind至确定端口而申请临时端口时已占满重试,等待资源释放
EAFNOSUPPORT地址族错误
EAGAIN资源暂时不可用无可用本地端口或路由缓存中无记录(?)重试,等待资源释放
EALREADY连接正在处理(非阻塞)上一个连接还未结束处理,可能是对返回EINPROGRESS重新调用
EBADFfd不可用fd已关闭或参数非法
ECONNREFUSED连接拒绝给定远端未监听,或见首次握手服务端RST重试
EFAULT地址错误地址指针超出用户空间
EINPROGRESS操作正在进行(非阻塞)connect无法立即完成使用getsockopt判断连接是出错还是已完成
EINTR调用中断调用被信号中断使用getsockopt判断连接是出错还是已完成
EISCONN套接字已连接使用getsockopt判断连接是出错还是已完成
ENETUNREACH网络不可达目的不可达重试
ENOTSOCK非套接字fd参数错误
EPROTOTYPE套接字协议错误
ETIMEDOUT连接超时远端无应答,可能因为系统繁忙重试

另附: 对connect下几种无法判断连接是否成功建立的处理方案的讨论http://www.madore.org/~david/computers/connect-intr.html

EINTR/EINPROGRESS/EALREADY代表的情况

If connect() is interrupted by a signal that is caught while blocked waiting to establish a connection, connect() shall fail and set connect() to [EINTR], but the connection request shall not be aborted, and the connection shall be established asynchronously.

If the connection cannot be established immediately and O_NONBLOCK is set for the file descriptor for the socket, connect() shall fail and set errno to [EINPROGRESS], but the connection request shall not be aborted, and the connection shall be established asynchronously. Subsequent calls to connect() for the same socket, before the connection is established, shall fail and set errno to [EALREADY].

When the connection has been established asynchronously, select() and poll() shall indicate that the file descriptor for the socket is ready for writing.

read(只涉及套接字)

errno含义可能情况致命解决
EAGAIN/EWOULDBLOCK操作将会阻塞(非阻塞)Buffer空重试
EBADFfd不可用fd已关闭或参数非法
EFAULT地址错误buffer超出用户空间
EINTR调用中断调用被信号中断重试
EINVAL参数错误fd不可读

write(只涉及套接字)

errno含义可能情况致命解决
EAGAIN/EWOULDBLOCK操作将会阻塞(非阻塞)Buffer已满或空闲空间不足重试
EBADFfd不可用fd已关闭或参数非法
EDESTADDRREQ需要目的地址套接字未连接
EFAULT地址错误buffer超出用户空间
EINTR调用中断调用被信号中断重试
EINVAL参数错误
EPIPE管道错误向读关闭的一端写,见写RST套接字
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值