`
lzy.je
  • 浏览: 150554 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

几个常见的 Socket 连接错误及原因

阅读更多

          下面列出了几个在客户与服务进程连接中常见的几个 Socket 错误,并分析了原因。后续再逐渐补充吧。

 

ECONNABORTED

          该错误被描述为“software caused connection abort”,即“软件引起的连接中止”。原因在于当服务和客户进程在完成用于 TCP 连接的“三次握手”后,客户 TCP 却发送了一个 RST (复位)分节,在服务进程看来,就在该连接已由 TCP 排队,等着服务进程调用 accept 的时候 RST 却到达了。POSIX 规定此时的 errno 值必须 ECONNABORTED。源自 Berkeley 的实现完全在内核中处理中止的连接,服务进程将永远不知道该中止的发生。服务器进程一般可以忽略该错误,直接再次调用accept。

 

ECONNABORTED

 

/* Linux system */

include/asm-alpha/errno.h:#define ECONNABORTED 53 /* Software caused connection
abort */
include/asm-generic/errno.h:#define ECONNABORTED 103 /* Software caused
connection abort */
include/asm-mips/errno.h:#define ECONNABORTED 130 /* Software caused connection
abort */

 

accept(2) man page 写道
[ECONNABORTED] A connection arrived, but it was closed while waiting on the listen queue.

 

ECONNRESET

          该错误被描述为“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”-“服务器过早终止”错误。

 

EPIPE

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

 

ETIMEDOUT

          错误被描述为“connect time out”,即“连接超时”,这种情况一般发生在服务器主机崩溃。此时客户 TCP 将在一定时间内(依具体实现)持续重发数据分节,试图从服务 TCP 获得一个 ACK 分节。当最终放弃尝试后(此时服务器未重新启动),内核将会向客户进程返回 ETIMEDOUT 错误。如果某个中间路由器判定该服务器主机已经不可达,则一般会响应“destination unreachable”-“目的地不可达”的ICMP消息,相应的客户进程返回的错误是 EHOSTUNREACH 或ENETUNREACH。当服务器重新启动后,由于 TCP 状态丢失,之前所有的连接信息也不存在了,此时对于客户端发来请求将回应 RST。如果客户进程对检测服务器主机是否崩溃很有必要,要求即使客户进程不主动发送数据也能检测出来,那么需要使用其它技术,如配置 SO_KEEPALIVE Socket 选项,或实现某些心跳函数。

 

作者:lzy.je
出处:http://lzy.iteye.com
本文版权归作者所有,只允许以摘要和完整全文两种形式转载,不允许对文字进行裁剪。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

// 2009.05.20 21:42 添加 ////

 

ENOPROTOOPT

          该错误不是一个 Socket 连接相关的错误。errno 给出该值可能由于,通过 getsockopt 系统调用来获得一个套接字的当前选项状态时,如果发现了系统不支持的选项参数就会引发该错误。

 

getsockopt/setsockopt(2) man page 写道
getsockopt, setsockopt -- get and set options on sockets.

#include <sys/socket.h>

int getsockopt(int socket, int level, int option_name,
void *restrict option_value, socklen_t *restrict option_len);

int setsockopt(int socket, int level, int option_name,
const void *option_value, socklen_t option_len);

Getsockopt() and setsockopt() manipulate the options associated with a socket. Options may exist at multiple protocol levels; they are always present at the uppermost "socket" level.

 

          此外,getsockopt 和 setsockopt 还可能引发以下错误:

 

getsockopt/setsockopt(2) man page 写道
ERRORS

The getsockopt() and setsockopt() system calls will succeed unless:

[EBADF] The argument socket is not a valid file descriptor.
[EFAULT] The address pointed to by option_value is not in a valid part of the process dress space. For getsockopt(), this error may also be returned if option_len is not in a valid part of the process address space.
[EINVAL] The option is invalid at the level indicated.
[ENOBUFS]Insufficient memory buffers are available.
[ENOPROTOOPT] The option is unknown at the level indicated.
[ENOTSOCK] The argument socket is not a socket (e.g., a plain file).

The setsockopt() system call will succeed unless:

[EDOM] The argument option_value is out of bounds.
[EISCONN]socket is already connected and a specified option cannot be set while this is the case.

 

// 2009.12.21 16:21 添加 ////

 

          一定要检查 write 方法的返回值,尤其是服务端程序,当返回 -1 的时候很有可能是“connection reset by peer”(ECONNRESET 104)。如果服务程序没有处理 SIGPIPE 信号的话,第二次程序在这条已经 close 的 socket 再次 write 时 SIGPIPE 信号就发送到 socket 关联的 owen 进程,也就是上面说的管道破裂,而该信号的默认处理是结束进程。今天不小心又因为这个浪费了两小时,在客户程序连续通信的时候,直接结束客户进程就造成服务进程也同时退出。开来还是太粗心。

 

  • 大小: 14.1 KB
3
0
分享到:
评论

相关推荐

    socket错误代码对应表

    除了上述提到的几个常见错误外,还有一些其他重要的错误代码: - **Socket error #10004 - Interrupted function call**:系统调用被中断。 - **Socket error #10013 - Permission denied**:权限不足。 - **Socket...

    librtmp长时间直播socket连接断开的原因

    然而,在长时间的直播过程中,可能会遇到socket连接断开的问题,这通常由以下几个因素导致: 1. **网络不稳定**:网络连接的不稳定性是最常见的问题。长时间的直播过程中,网络环境可能发生变化,如Wi-Fi信号弱、...

    Socket长连接心跳

    实现Socket长连接心跳主要涉及以下几个关键知识点: 1. **建立Socket连接**:首先,客户端通过Socket类创建一个到服务器的连接。这通常涉及DNS解析、TCP三次握手等网络协议过程。 2. **心跳包设计**:心跳包应尽...

    TP使用socket对接联通SGIP

    在实际应用中,对接SGIP协议的过程可能会涉及以下几个关键步骤: 1. **配置socket连接**:首先,你需要在PHP中创建一个socket资源,指定服务器地址和端口,然后使用`socket_connect()`函数建立连接。 2. **登录...

    socket重连解决

    在实际应用中,由于各种原因(如网络中断、服务器重启、超时等),Socket连接可能会断开,这时就需要进行重连处理以确保服务的稳定性和可靠性。本文将详细探讨Socket重连的原理、方法以及实现策略。 一、Socket连接...

    Android端socket框架EasySocket

    使用EasySocket通常包括以下几个步骤: 1) 引入库:在项目build.gradle文件中添加EasySocket的依赖。 2) 初始化:创建一个ServerConfig对象,设置服务器地址、端口等信息,并调用EasySocket.init()方法启动框架。 3)...

    Socket网络编程3

    在这个部分,我们将会探讨以下几个关键知识点: 1. **TCP协议基础**:TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它通过三次握手建立连接,并在数据传输完成后...

    socket聊天程序

    在这个"socket聊天程序"中,我们主要涉及到以下几个关键知识点: 1. **Socket概念**:Socket是网络通信的一种接口,它提供了一种标准的方式让运行在不同主机上的应用程序能够通过网络进行通信。在TCP/IP协议栈中,...

    Android socket即时通信

    服务器端的实现包括以下几个步骤: 1. 建立服务器端Socket并绑定到特定的IP地址和端口号。 2. 监听客户端的连接请求,使用`accept()`方法接收连接。 3. 当有客户端连接时,创建一个新的Socket对象来处理这个连接,并...

    Socket模式网关.rar

    它首先需要知道服务器的IP地址和端口号,然后建立Socket连接,发送数据,并接收服务器的回应。 3. **多线程或异步处理**:为了处理多个并发连接,Socket模式网关通常采用多线程或异步I/O模型。这样,每个连接都可以...

    SocketDemo c++工程实例

    在C++中,使用Socket编程主要包括以下几个步骤: 1. **创建Socket**:调用`socket()`函数创建一个Socket对象,指定其类型(TCP或UDP)和协议(如IPv4或IPv6)。 2. **服务器端绑定地址和端口**:服务器需要先调用`...

    实战Linux Socket编程

    在Linux Socket编程中,主要涉及以下几个关键概念: 1. **创建Socket**:使用`socket()`函数创建一个Socket描述符,这代表了通信的起点。你需要指定协议族(如AF_INET用于IPv4)、套接字类型(如SOCK_STREAM用于TCP...

    socket 创建聊天室

    在IT领域,Socket编程是一种常见的网络通信方式,它允许客户端和服务端进行双向数据传输,从而实现各种网络应用,如创建聊天室。在这个场景下,我们将深入探讨如何利用Socket技术来构建一个简单的聊天室。 首先,...

    socket编程样例代码

    当有新的连接请求时,服务器会接受连接并创建一个新的Socket用于与客户端通信。 - 客户端:创建Socket,指定服务器的IP和端口,然后发起连接请求。连接成功后,就可以通过Socket进行数据的发送和接收。 2. **UDP...

    LINUX下C++socket

    Socket编程涉及到几个关键概念: 1. **Socket接口**:Socket是进程间通信的一种方式,特别是在网络环境中。它提供了标准的API,使得程序能够创建、连接、读写和关闭网络连接。 2. **套接字类型**:在创建Socket时...

    socket测试工具

    1. 创建并管理socket连接:支持设置不同的协议(如TCP或UDP)、端口、IP地址等参数。 2. 发送和接收数据:提供输入框或脚本支持,以便构造和发送任意格式的数据,并记录接收到的响应。 3. 错误模拟:模拟网络故障、...

    SOCKET通信调试工具

    SOCKET通信的核心概念包括以下几个方面: 1. **TCP/IP协议栈**:SOCKET通信基于TCP/IP协议栈,它是互联网通信的基础。TCP(传输控制协议)提供面向连接、可靠的数据传输服务,而IP(互联网协议)负责将数据包从源...

    SocketTest

    在SocketTest项目中,我们可以学习到以下几个关键知识点: 1. **Socket基础知识**:Socket是网络通信的基础,它提供了进程间的通信能力。在TCP/IP协议族中,Socket主要分为两种类型:流式Socket(SOCK_STREAM)和...

    通用TCP/UDP异步SOCKET通讯封装及Demo

    对于TCP/UDP异步SOCKET的封装,通常需要实现以下几个关键部分: 1. **连接管理**:包括建立、维护和断开连接。对于TCP,需要实现连接请求的发起和接收;对于UDP,由于是无连接的,主要关注数据的发送和接收。 2. *...

Global site tag (gtag.js) - Google Analytics