文档章节

【整理】Socket编程之非阻塞connect(二)

摩云飞
 摩云飞
发布于 2012/11/08 18:15
字数 1768
阅读 453
收藏 9
点赞 0
评论 0


      socket api 存在一批核心接口,而这一批核心接口就是几个看似简单的函数,尽管实际上这些函数没有一个是简单。connect 函数就是这些核心接口中的一个函数,它完成主动连接的过程。 

connect 函数的功能对于 TCP 来说就是完成面向连接的协议的连接过程,它的函数原型:

linux下

#include<sys/socket.h>
#include<sys/types.h>
int connect(int sockfd, const struct sockaddr* server_addr, socklen_t addrlen)
windows下
int connect(
    SOCKET s,     // 没绑定套接口描述字
    const struct sockaddr FAR *name,   // 目标地址指针,目标地址中必须包含IP和端口信息。
    int namelen   // name的长度
    );

       面向连接的协议,在建立连接的时候总会有一方先发送数据(SYN),那么谁调用了 connect 谁就是先发送数据的一方。如此理解 connect 三个参数就容易了。我必需指定数据发送的目的地址,同时也必需指定数据从哪里发送,这正好是 connect 的前两个参数,而第三个参数是为第二个参数服务的。

参数 sockfd 
      指定数据发送的套接字,解决从哪里发送的问题。内核需要维护大量 I/O 通道,所以用户必需通过这个参数告诉内核从哪个 I/O 通道(此处就是从哪个 socket 接口)中发送数据。

参数 server_addr 
      指定数据发送的目的地,也就是服务器端的地址。这里服务器是针对 connect 说的,因为 connect 是主动连接的一方调用的,所以相应的要存在一个被连接的一方,被动连接的一方需要调用 listen 以接受 connect 的连接请求,如此被动连接的一方就是服务器了。

参数 addrlen  
      指定 server_addr 结构体的长度。我们知道系统中存在大量的地址结构,但 socket 接口只是通过一个统一的结构来指定参数类型,所以需要指定一个长度,以使内核在进行参数复制的时候有个界限。 

返回值:没有错误发生,返回0;否则返回 SOCKET_ERROR(-1) 。

====================

      与所有的 socket 网络接口一样,connect 总会在某个时候可能失败,此时它会返回 -1 ,相应的 errno 会被设置,用户可能通过这个值确定是哪个错误。常见的错误有对方主机不可达或者超时错误,也可以是对方主机没有相应的进程在对应端口等待

connect 函数可用于 面向连接套接字 也可用于 无连接套接字

无连接套接字 :对于无连接的套接字 (SOCK_DGRAM) ,该套接字与目标地址之间建立默认的对应关系,且在本地保存了对端的地址,这样后续的读写操作可以默认以连接的对端为操作对象,网络数据交互发生时可以直接使用 send ,而不是用 sendto 来向该地址发送数据;内核会丢弃所有发送给该套接字的源地址不是 connect 地址的报文。再次调用 connect 函数,若此时 name 和 namelen 两个参数均为空指针,就会将该套接字恢复为未连接状态,再调用 send 函数,系统会提示 WSAENOTCONN 错误码。

面向连接套接字 :面向连接的套接字 (SOCK_STREAM) ,函数 connect 会引起调用端主动进行 TCP 的三次握手过程。结果通常是成功连接WSAETIMEDOUT (多次发送SYN报文,始终未收到回复)、WSAECONNREFUSED (目标主机返回 RST) 等。

  当对端机器 crash 或者网络连接被断开(比如路由器不工作,网线断开等),此时发送数据给对端然后,读取本端 socket 会返回 ETIMEDOUT 或者 EHOSTUNREACH 或者 ENETUNREACH (后两个是中间路由器判断服务器主机不可达的情况)。

  当对端机器 crash 之后又重新启动,然后客户端再向原来的连接发送数据,因为服务器端已经没有原来的连接信息,此时服务器端回送 RST 给客户端,此时客户端读本地端口返回 ECONNRESET 错误。

  当服务器所在的进程正常或者异常关闭时,会对所有打开的文件描述符进行 close ,因此对于连接的 socket 描述符则会向对端发送 FIN 分节进行正常关闭流程。对端在收到 FIN 之后端口变得可读,此时读取端口会返回 0 表示到了文件结尾(对端不会再发送数据)。 

  当一端收到 RST 导致读取 socket 返回 ECONNRESET ,此时如果再次调用 write 发送数据给对端则触发 SIGPIPE 信号,信号默认终止进程,如果忽略此信号或者从 SIGPIPE 的信号处理程序返回则 write 出错返回 EPIPE 。

================================= =====
1) Broken PIPE 的字面意思是“管道破裂”。Broken PIPE 产生的原因是该管道的读端被关闭。
2) Broken PIPE 经常发生在 Client 端通过 Socket 发送信息到 Server 端后,就关闭当前 Socket , 之后 Server 端回复信息给 Client 端时。
3) 发生 Broken PIPE 错误时,调用写的进程会收到 SIGPIPE 信号,默认动作是导致当前进程终止。
4) Broken PIPE 最直接的意思是:写入端出现的时候,PIPE 的另一端却休息或退出了,因此造成没有及时取走管道中的数据,从而系统异常退出。

Client 端通过 PIPE 发送信息到 Server 端后,就关闭 Client 端 Socket , 这时 Server 端返回信息给 Client 端时就会产生 Broken PIPE 信号。

======================================

  可以看出,只有当本地端口主动发送消息给对端时,才能检测出连接异常中断的情况,搭配 select 进行多路分离的时候,socket 收到 RST 或者 FIN 时候,select 返回可读(心跳消息就是用于检测连接的状态)。也可以使用 socket 的 KEEPLIVE 选项,依赖 socket 本身侦测 socket 连接异常中断的情况。


错误信息:

EACCES, EPERM:用户试图在套接字广播标志没有设置的情况下连接广播地址或由于防火墙策略导致连接失败。
EADDRINUSE:本地地址处于使用状态。
EAFNOSUPPORT:参数 serv_add 中的地址非法。
EAGAIN:没有足够空闲的本地端口。
EALREADY:套接字为非阻塞套接字,并且原来的连接请求还未完成。
EBADF:非法的文件描述符。
ECONNREFUSED:远程地址并没有处于监听状态。
EFAULT:指向套接字结构体的地址非法。
EINPROGRESS:套接字为非阻塞套接字,且连接请求没有立即完成。
EINTR:系统调用的执行由于捕获中断而中止。
EISCONN:已经连接到该套接字。
ENETUNREACH:网络不可到达。
ENOTSOCK:文件描述符不与套接字相关。

ETIMEDOUT:连接超时。


© 著作权归作者所有

共有 人打赏支持
摩云飞
粉丝 364
博文 352
码字总数 952690
作品 0
徐汇
程序员
【整理】Socket编程之非阻塞connect(一)

非阻塞 connect: 在 TCP socket 被设置为非阻塞的情况下调用 connect ,若没有立即返回成功,则会返回 -1 以及 errno = EINPROGRESS 的 错误,其表示连接操作正在进行中,但是尚未完成,与此...

摩云飞 ⋅ 2012/11/08 ⋅ 0

非阻塞connect对于select时应注意的问题

对于面向连接的socket类型(SOCKSTREAM,SOCKSEQPACKET)在读写数据之前必须建立连接。 首先服务器端socket必须在一个客户端知道的地址进行监听,也就是创建socket之后必须调用bind绑定到一个指定...

地狱的烈火 ⋅ 2013/02/22 ⋅ 0

JAVA SOCKET connect超时设置是如何实现的?

JAVA SOCKET编程中 SOCKET中connect方法是可以设置连接超时时间的,如下: java.net.Socketpublic void connect(SocketAddress endpoint, int timeout) throws IOException 注:timeout为0表......

智深 ⋅ 2012/11/28 ⋅ 2

python中的网络编程

socket()函数: 使用socket.socket()函数来创建套接字: socket(socketfamily,sockettype,protocol=0) socketfamilu可以是AFINET或AFUNIX.sockettype可以是SOCKSTREAM(面向连接的)或SOCKDGR......

指尖跳动的精灵 ⋅ 2015/04/06 ⋅ 0

select在socket中的运用

Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如 connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思...

zhengyijie ⋅ 2012/12/21 ⋅ 3

Python入门(十五) socket编程

写过Socket网络编程的代码,大致都知道一个tcp服务器的主要步骤:socket-->bind-->listen-->accept-->recv/send-->close, tcp客户端的主要 步骤:socket-->connect-->recv/send-->close。有上......

kaedehao ⋅ 2015/08/25 ⋅ 0

Python Socket编程(一)

Python 提供了两个级别访问的网络服务: 1.Socket:低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。 2.SocketServer:高级...

zhangyahui7116 ⋅ 2017/01/20 ⋅ 0

Socket阻塞模式和非阻塞模式

阻塞模式和非阻塞模式 网络不是一个稳定可靠的,存在各种异常情况,比如connect和服务端 三次握手失败,那这个函数就会阻塞,各种问题,可以设置非阻塞, 超时处理,1可以用Socket进行设置,但是考虑...

超级极客 ⋅ 2017/07/17 ⋅ 0

Linux下阻塞与非阻塞IO

阻塞:顾名思义,就是指在执行设备操作时若不能获得资源则挂起操作,直到满足可操作的条件后再进行操作,被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件满足。 非阻塞:...

技术小阿哥 ⋅ 2017/11/28 ⋅ 0

阻塞与非阻塞个人小结

1.connect函数响应中断返回后仍然回到函数的调用。 实践证明,对于一个非阻塞的socket,如果在调用connect函数时,如果发生中断,这函数响应中断,但当中断返回时,继续connect函数的调用,直...

lichao19881026 ⋅ 2014/05/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 33分钟前 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 38分钟前 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

马氏距离与欧氏距离

马氏距离 马氏距离也可以定义为两个服从同一分布并且其协方差矩阵为Σ的随机变量之间的差异程度。 如果协方差矩阵为单位矩阵,那么马氏距离就简化为欧氏距离,如果协方差矩阵为对角阵,则其也...

漫步当下 ⋅ 昨天 ⋅ 0

聊聊spring cloud的RequestRateLimiterGatewayFilter

序 本文主要研究一下spring cloud的RequestRateLimiterGatewayFilter GatewayAutoConfiguration @Configuration@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMi......

go4it ⋅ 昨天 ⋅ 0

Spring clound 组件

Spring Cloud技术应用从场景上可以分为两大类:润物无声类和独挑大梁类。 润物无声,融合在每个微服务中、依赖其它组件并为其提供服务。 Ribbon,客户端负载均衡,特性有区域亲和、重试机制。...

英雄有梦没死就别停 ⋅ 昨天 ⋅ 0

Confluence 6 重新获得站点备份文件

Confluence 将会创建备份,同时压缩 XML 文件后存储熬你的 <home-directory>/backups> 目录中。你需要自己访问你安装的 Confluence 服务器,并且从服务器上获得这个文件。 运行从 Confluence...

honeymose ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部