在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

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

握手结束客户端RST

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

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

数据传送部分

服务端主机崩溃

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

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

挥手部分

服务端进程终止或关机

​ 服务端由于进程崩溃或者手动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

地址已被使用

绑定已使用地址或申请临时端口时已占满

临时端口已满时重试

EBADF

fd不可用

fd已关闭或参数非法

EINVAL

参数错误

套接字重复绑定或参数错误

ENOTSOCK

非套接字

fd参数错误

listen

errno

含义

可能情况

致命

解决

EADDRINUSE

地址已被使用

监听已监听端口或未bind至确定端口而申请临时端口时已占满

临时端口已满时重试

EBADF

fd不可用

fd已关闭或参数非法

ENOTSOCK

非套接字

fd参数错误

EOPNOTSUPP

操作不支持

只支持SOCK_STREAM类套接字(TCP)

accept

errno

含义

可能情况

致命

解决

EWOULDBLOCK/EAGAIN

资源暂时不可用

(非阻塞)队列中无完成握手的连接

重试或处理其他事务

EBADF

fd不可用

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重新调用

EBADF

fd不可用

fd已关闭或参数非法

ECONNREFUSED

连接拒绝

给定远端未监听,或见首次握手服务端RST

重试

EFAULT

地址错误

地址指针超出用户空间

EINPROGRESS

操作正在进行

(非阻塞)connect无法立即完成

使用getsockopt判断连接是出错还是已完成

EINTR

调用中断

调用被信号中断

使用getsockopt判断连接是出错还是已完成

EISCONN

套接字已连接

使用getsockopt判断连接是出错还是已完成

ENETUNREACH

网络不可达

见目的不可达

重试

ENOTSOCK

非套接字

fd参数错误

EPROTOTYPE

套接字协议错误

ETIMEDOUT

连接超时

远端无应答,可能因为系统繁忙

重试

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

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空

重试

EBADF

fd不可用

fd已关闭或参数非法

EFAULT

地址错误

buffer超出用户空间

EINTR

调用中断

调用被信号中断

重试

EINVAL

参数错误

fd不可读

write(只涉及套接字)

errno

含义

可能情况

致命

解决

EAGAIN/EWOULDBLOCK

操作将会阻塞

(非阻塞)Buffer已满或空闲空间不足

重试

EBADF

fd不可用

fd已关闭或参数非法

EDESTADDRREQ

需要目的地址

套接字未连接

EFAULT

地址错误

buffer超出用户空间

EINTR

调用中断

调用被信号中断

重试

EINVAL

参数错误

EPIPE

管道错误

向读关闭的一端写,见写RST套接字

套接字服务器打开显示未知文件异常,TCP-socket异常情况相关推荐

  1. java 函数式编程 示例_Java套接字编程–套接字服务器,客户端示例

    java 函数式编程 示例 Welcome to Java Socket programming example. Every server is a program that runs on a s ...

  2. 目录打开显示提示文件或目录损坏且无法读取、文件或目录损坏且无法读取的破解之道

    咱们在平日工作时,通常都会将资料放进不同的目录中,方便咱们找到,随着时间的推移就会产生有越来越多目录.最近有位用户了这样一个问题,就是目录无论怎么都无法打开,这样就无法浏览.使用里面的资料了,影响到了 ...

  3. c 服务器和android客户端,通过TCP与c + +(套接字服务器)conect android(套接字客户端)...

    我有一个实现在大学项目中做,我不知道如何avchive它!我的问题就像标题所说的那样,通过套接字将C++与android连接起来.通过TCP与c + +(套接字服务器)conect android(套 ...

  4. WIN10 管家婆套接字服务器 自启动

    开始 --运行--gpedit.msc--计算机配置-windows设置--安全设置--本地策略--安全选项--用户帐户控制:以管理员批准模式运行所有管理员--禁用 添加套接字服务器的快捷方式到:c: ...

  5. 服务器复制性能下降,使用套接字 API 程序将数据复制到 TCP 服务器时Windows性能...

    使用套接字 API 程序将数据复制到 TCP 服务器时Windows性能 12/04/2020 本文内容 本文提供了使用套接字 API 程序将数据复制到 TCP 服务器时出现性能缓慢Windows解决 ...

  6. 《UNIX网络编程 卷1:套接字联网API》学习笔记——基本TCP套接字编程

    UNIX网络编程--基本TCP套接字编程 socket 函数 connect 函数 bind 函数 listen 函数 accept 函数 fork 和 exec 函数 并发服务器 close 函数 ...

  7. java套接字客户端_使用Java从客户端套接字读取数据(Read data from a client socket in Java)...

    使用Java从客户端套接字读取数据(Read data from a client socket in Java) 我编写了从客户端套接字发送/接收数据的代码. 发送数据步骤已成功完成,但是当我想从套 ...

  8. 一个简单的socket套接字服务器,Python

    (1)用Python实现一个简单的套接字socket服务器例子,该服务器在接受客户端连接后,每隔一秒从a到z的字符中随机选一个发送给客户端. import socketserver import ti ...

  9. 【Linux网络编程】网络基础 和 socket套接字 服务器与客户端 详细案例说明

    目录 前言 一.网络编程三要素 1.IP地址 2.通信协议 3.端口号 二.SOCKET套接字 SOCKET概述 SOCKET分类 三.代码实现 1.编程思路 2.建立服务器 服务器完整代码 3.建立 ...

最新文章

  1. ArcFace - 人脸识别
  2. 「模型解读」“不正经”的卷积神经网络
  3. windows 报错 没有文件扩展.vbs的脚本引擎 解决方法
  4. 随笔-使用时间管理有感
  5. “‘天池·TEENTOP杯’AI少年挑战赛”正式启动!
  6. BugkuCTF-Crypto题给你私钥吧
  7. finallshell使用_FinalShell使用---Xshell的良心国产软件
  8. 如何免费注册使用虚拟主机和二级域名建站
  9. 【06年博文搬家】一个修改时间的批处理程序
  10. SSH dao层异常 org.hibernate.HibernateException: No Session found for current thread
  11. 中级微观经济学:Chap 35 外部效应
  12. 通过 百度网盘 分享文件
  13. 第一章 DirectX 计算机图形学(上)
  14. nofllow html5,NoFollow:高亮显示nofollow标签
  15. 金融行业市场策划案例(共12份)
  16. 2023年中职网络安全竞赛解析——隐藏信息探索
  17. php图片素描化,把照片做成素描效果 照片做成素描
  18. 小爱同学上线win10商店
  19. Mysql CASE方法条件怎么加and或or
  20. 安装oracle12f 闪退,安装oracle ,调用图形界面java卡死,

热门文章

  1. bug:ORA-20002: Directory creation failed
  2. python制作应用程序_如何将python应用制作成容器镜像?
  3. html运行老是页面加载错误,为啥总说网页有错误?
  4. 5G PDCCH时频资源之CORESET概要
  5. 博途PLC位变量计数编程(SCL应用)
  6. sql server 2014 外围应用配置器去哪了??
  7. 小程序插入激励视频广告例子
  8. 双11小黑盒很炫酷?咱们用CSS变量来改进一下!
  9. vscode连接CentOS云服务器其实没有那么复杂!
  10. m3u8及TS文件下载解密:m3u8文件下载及分析(三)