Linux网络编程socket错误分析
socket错误码:
EINTR:4
阻塞的操作被取消阻塞的调用打断。如设置了发送接收超时,就会遇到这种错误。
只能针对阻塞模式的socket。读,写阻塞的socket时,-1返回,错误号为INTR。另外,如果出现EINTR即errno为4,错误描述Interrupted system call,操作也应该继续。如果recv 的返回值为0,那表明连接已经断开,接收操作也应该结束。
ETIMEOUT:110
1、操作超时。一般设置了发送接收超时,遇到网络繁忙的情况,就会遇到这种错误。
2、服务器做了读数据做了超时限制,读时发生了超时。
3、错误被描述为“connect time out”,即“连接超时”,这种情况一般发生在服务器主机崩溃。此时客户TCP 将在一定时间内(依具体实现)持续重发数据分节,试图从服务TCP 获得一个ACK 分节。当最终放弃尝
试后(此时服务器未重新启动),内核将会向客户进程返回ETIMEDOUT 错误。如果某个中间路由器判定该服务器主机已经不可达,则一般会响应“destination unreachable”-“目的地不可达”的ICMP消息,相应的客户进程返回的错误是EHOSTUNREACH 或ENETUNREACH。当服务器重新启动后,由于TCP 状态丢失,之前所有的连接信息也不存在了,此时对于客户端发来请求将回应RST。如果客户进程对检测服务器主机是否崩溃很有必要,要求即使客户进程不主动发送数据也能检测出来,那么需要使用其它技术,如配置SO_KEEPALIVE Socket 选项,或实现某些心跳函数。
EAGAIN:
1、Send返回值小于要发送的数据数目,会返回EAGAIN和EINTR。
2、recv 返回值小于请求的长度时说明缓冲区已经没有可读数据,但再读不一定会触发EAGAIN,有可能返回0表示TCP连接已被关闭。
3、当socket是非阻塞时,如返回此错误,表示写缓冲队列已满,可以做延时后再重试.
4、在Linux进行非阻塞的socket接收数据时经常出现Resource temporarily unavailable,errno 代码为11(EAGAIN),表明在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏socket的同步,不用管它,下次循环接着recv就可以。对非阻塞socket而言,EAGAIN不是一种错误。
EPIPE:
1、Socket 关闭,但是socket号并没有置-1。继续在此socket上进行send和recv,就会返回这种错误。这个错误会引发SIGPIPE信号,系统会将产生此EPIPE错误的进程杀死。所以,一般在网络程序中,首先屏蔽此消息,以免发生不及时设置socket进程被杀死的情况。
2、write(..) on a socket that has been closed at the other end will cause a SIGPIPE.
3、错误被描述为“broken pipe”,即“管道破裂”,这种情况一般发生在客户进程不理会(或未及时处理)Socket 错误,继续向服务TCP 写入更多数据时,内核将向客户进程发送SIGPIPE 信号,该信号默认会使进程终止(此时该前台进程未进行core dump)。结合上边的ECONNRESET 错误可知,向一个FIN_WAIT2 状态的服务TCP(已ACK 响应FIN 分节)写入数据不成问题,但是写一个已接收了RST 的Socket 则是一个错误。
EBADF:
read(..) or write(..) on a locally closed socket will return EBADF
EFAULT:
地址错误。
EBUSY:
ECONNREFUSED:
1、拒绝连接。一般发生在连接建立时。
拔服务器端网线测试,客户端设置keep alive时,recv较快返回0,先收到ECONNREFUSED (Connection refused)错误码,其后都是ETIMEOUT。
2、an error returned from connect(), so it can only occur in a client (if a client is defined as the party that initiates the connection
ECONNRESET:
1、在客户端服务器程序中,客户端异常退出,并没有回收关闭相关的资源,服务器端会先收到ECONNRESET错误,然后收到EPIPE错误。
2、连接被远程主机关闭。有以下几种原因:远程主机停止服务,重新启动;当在执行某些操作时遇到失败,因为设置了“keep alive”选项,连接被关闭,一般与ENETRESET一起出现。
3、远程端执行了一个“hard”或者“abortive”的关闭。应用程序应该关闭socket,因为它不再可用。当执行在一个UDP socket上时,这个错误表明前一个send操作返回一个ICMP “port unreachable”信息。
4、如果client关闭连接,server端的select并不出错(不返回-1,使用select对唯一一个socket 进行non- blocking检测),但是写该socket就会出错,用的是send.错误号:ECONNRESET.读(recv)socket并没有返回错误。
5、该错误被描述为“connection reset by peer”,即“对方复位连接”,这种情况一般发生在服务进程较客户进程提前终止。当服务进程终止时会向客户TCP 发送FIN 分节,客户TCP 回应ACK,服务TCP 将转入FIN_WAIT2 状态。此时如果客户进程没有处理该FIN (如阻塞在其它调用上而没有关闭Socket 时),则客户TCP 将处于CLOSE_WAIT 状态。当客户进程再次向FIN_WAIT2 状态的服务TCP 发送数据时,则服务TCP 将立刻响应RST。一般来说,这种情况还可以会引发另外的应用程序异常,客户进程在发送完数据后,往往会等待从网络IO接收数据,很典型的如read 或readline 调用,此时由于执行时序的原因,如果该调用发生在RST 分节收到前执行的话,那么结果是客户进程会得到一个非预期的EOF 错误。此时一般会输出“server terminated prematurely”-“服务器过早终止”错误。
EINV AL:
无效参数。提供的参数非法。有时也会与socket的当前状态相关,如一个socket并没有进入listening状态,
此时调用accept,就会产生EINV AL错误。
EMFILE:
打开了太多的socket。对进程或者线程而言,每种实现方法都有一个最大的可用socket数目处理,或者是全局的,或者是局部的。
EWOULDBLOCK:EAGAIN
资源暂时不可用。这个错误是从对非阻塞socket进行的不能立即结束的操作返回的,如当没有数据在队列中可以读时,调用recv。并不是fatal错误,稍后操作可以被重复。调用在一个非阻塞的SOCK_STREAM socket 上调用connect时会产生这个错误,因为有时连接建立必须消耗一定的时间。
ENOTCONN
在一个没有建立连接的socket上,进行read,write操作会返回这个错误。出错的原因是socket没有标识地址。Setsoc也可能会出错。
ECONNRESET
Connection reset by peer.
连接被远程主机关闭。有以下几种原因:远程主机停止服务,重新启动;当在执行某些操作时遇到失败,因为设置了“keep alive”选项,连接被关闭,一般与ENETRESET一起出现。
ECONNABORTED
1、软件导致的连接取消。一个已经建立的连接被host方的软件取消,原因可能是数据传输超时或者是协议错误。
2、该错误被描述为“software caused connection abort”,即“软件引起的连接中止”。原因在于当服务和客户进程在完成用于TCP 连接的“三次握手”后,客户TCP 却发送了一个RST (复位)分节,在服务进程看来,就在该连接已由TCP 排队,等着服务进程调用accept 的时候RST 却到达了。POSIX 规定此时的errno 值必须ECONNABORTED。源自Berkeley 的实现完全在内核中处理中止的连接,服务进程将永远不知道该中止的发生。服务器进程一般可以忽略该错误,直接再次调用accept。
当TCP协议接收到RST数据段,表示连接出现了某种错误,函数read将以错误返回,错误类型为ECONNERESET。并且以后所有在这个套接字上的读操作均返回错误。错误返回时返回值小于0。
ENETUNREACH
网络不可达。Socket试图操作一个不可达的网络。这意味着local的软件知道没有路由到达远程的host。
ENETRESET
网络重置时丢失连接。
由于设置了"keep-alive"选项,探测到一个错误,连接被中断。在一个已经失败的连接上试图使用setsockopt操作,也会返回这个错误。
EINPROGRESS:
操作正在进行中。一个阻塞的操作正在执行。
ENOTSOCK:
在非socket上执行socket操作。
EDESTADDRREQ:
需要提供目的地址。
在一个socket上的操作需要提供地址。如往一个ADDR_ANY 地址上进行sendto操作会返回这个错误。
EMSGSIZE:
消息体太长。
发送到socket上的一个数据包大小比内部的消息缓冲区大,或者超过别的网络限制,或是用来接收数据包的缓冲区比数据包本身小。
EPROTOTYPE
协议类型错误。标识了协议的Socket函数在不支持的socket上进行操作。如ARPA Internet UDP协议不能被标识为SOCK_STREAM socket类型。
ENOPROTOOPT
该错误不是一个Socket 连接相关的错误。errno 给出该值可能由于,通过getsockopt 系统调用来获得一个套接字的当前选项状态时,如果发现了系统不支持的选项参数就会引发该错误。
EPROTONOSUPPORT
不支持的协议。系统中没有安装标识的协议,或者是没有实现。如函数需要SOCK_DGRAM socket,但是标识了stream protocol.。
ESOCKTNOSUPPORT
Socket类型不支持。指定的socket类型在其address family中不支持。如可选选中选项SOCK_RAW,但实现并不支持SOCK_RAW sockets。
EOPNOTSUPP
Operation not supported.
The attempted operation is not supported for the type of object referenced. Usually this occurs when a socket descriptor to a socket that cannot support this operation, for example, trying to accept a connection on a datagram socket.
EPFNOSUPPORT
Protocol family not supported.
The protocol family has not been configured into the system or no implementation for it exists. Has a slightly different meaning to EAFNOSUPPORT, but is interchangeable in most cases, and all Windows Sockets functions that return one of these specify EAFNOSUPPORT.
EAFNOSUPPORT
Address family not supported by protocol family.
An address incompatible with the requested protocol was used. All sockets are created with an associated "address family" (i.e. AF_INET for Internet Protocols) and a generic protocol type (i.e. SOCK_STREAM). This error will be returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, e.g. in sendto.
EADDRINUSE
Address already in use.
recv函数Only one usage of each socket address (protocol/IP address/port) is normally permitted. This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that wasn't closed properly, or one that is still in the process of closing. For server applications that need to bind multiple sockets to the same port number, consider using setsockopt(SO_REUSEADDR). Client applications usually need not call bind at all - connect will choose an unused port automatically. When bind is called with a wild-card address (involving ADDR_ANY), a EADDRINUSE error could be delayed until the specific address is "committed." This could happen with a call to other function later, including connect, listen, Connect or JoinLeaf.
EADDRNOTA V AIL
Cannot assign requested address.
The requested address is not valid in its context. Normally results from an attempt to bind to an address that is not valid for the local machine. This can also result from connect, sendto, Connect, JoinLeaf, or SendTo when the remote address or port is not valid for a remote machine (e.g. address or port 0).
ENETDOWN
Network is down.
A socket operation encountered a dead network. This could indicate a serious failure of the network system (i.e. the protocol stack that the WinSock DLL runs over), the network interface, or the local network itself.
ENOBUFS
No buffer space available.
An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
EISCONN
Socket is already connected.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论