`

非阻塞connect编程

阅读更多

非阻塞模式有3种用途

  1.三次握手同时做其他的处理。connect要花一个往返时间完成,从几毫秒的局域网到几百毫秒或几秒的广域网。这段时间可能有一些其他的处理要执行,比如数据准备,预处理等。
  2.用这种技术建立多个连接。这在web浏览器中很普遍.
  3.由于程序用select等待连接完成,可以设置一个select等待时间限制,从而缩短connect超时时间。多数实现中,connect的超时时间在75秒到几分钟之间。有时程序希望在等待一定时间内结束,使用非阻塞connect可以防止阻塞75秒,在多线程网络编程中,尤其必要。 例如有一个通过建立线程与其他主机进行socket通信的应用程序,如果建立的线程使用阻塞connect与远程通信,当有几百个线程并发的时候,由于网络延迟而全部阻塞,阻塞的线程不会释放系统的资源,同一时刻阻塞线程超过一定数量时候,系统就不再允许建立新的线程(每个进程由于进程空间的原因能产生的线程有限),如果使用非阻塞的connect,连接失败使用select等待很短时间,如果还没有连接后,线程立刻结束释放资源,防止大量线程阻塞而使程序崩溃。

 

 

 

// 设置套接字为非阻塞

flags = fcntl(sock[i],F_GETFL,0);

fcntl(sock[i],F_SETFL,flags|O_NONBLOCK);

 

 

fcntl(文件描述词操作

 

相关函数
open,flock
表头文件
#include<unistd.h>
#include<fcntl.h>
定义函数
int fcntl(int fd , int cmd);
int fcntl(int fd,int cmd,long arg);
int fcntl(int fd,int cmd,struct flock * lock);
函数说明
fcntl()用来操作文件描述词的一些特性。参数fd代表欲设置的文件描述词,参数cmd代表欲操作的指令。
有以下几种情况:
F_DUPFD用来查找大于或等于参数arg的最小且仍未使用的文件描述词,并且复制参数fd的文件描述词。执行成功则返回新复制的文件描述词。请参考dup2()。F_GETFD取得close-on-exec旗标。若此旗标的FD_CLOEXEC位为0,代表在调用exec()相关函数时文件将不会关闭。
F_SETFD 设置close-on-exec 旗标。该旗标以参数arg 的FD_CLOEXEC位决定。
F_GETFL 取得文件描述词状态旗标,此旗标为open()的参数flags。
F_SETFL 设置文件描述词状态旗标,参数arg为新旗标,但只允许O_APPEND、O_NONBLOCK和O_ASYNC位的改变,其他位的改变将不受影响。
F_GETLK 取得文件锁定的状态。
F_SETLK 设置文件锁定的状态。此时flcok 结构的l_type 值必须是F_RDLCK、F_WRLCK或F_UNLCK。如果无法建立锁定,则返回-1,错误代码为EACCES 或EAGAIN。
F_SETLKW F_SETLK 作用相同,但是无法建立锁定时,此调用会一直等到锁定动作成功为止。若在等待锁定的过程中被信号中断时,会立即返回-1,错误代码为EINTR。参数lock指针为flock 结构指针,定义如下
struct flcok
{
short int l_type; /* 锁定的状态*/
short int l_whence;/*决定l_start位置*/
off_t l_start; /*锁定区域的开头位置*/
off_t l_len; /*锁定区域的大小*/
pid_t l_pid; /*锁定动作的进程*/
};
l_type 有三种状态:
F_RDLCK 建立一个供读取用的锁定
F_WRLCK 建立一个供写入用的锁定
F_UNLCK 删除之前建立的锁定
l_whence 也有三种方式:
SEEK_SET 以文件开头为锁定的起始位置。
SEEK_CUR 以目前文件读写位置为锁定的起始位置
SEEK_END 以文件结尾为锁定的起始位置。
返回值
成功则返回0,若有错误则返回-1,错误原因存于errno.

 

 

 

此时socket设置为非阻塞,connect调用后,无论连接是否建立立即返回-1,同时将errno(包含errno.h就可以直接使用)设置为EINPROGRESS, 表示此时tcp三次握手仍旧进行,如果errno不是EINPROGRESS,则说明连接错误,程序结束。(当客户端和服务器端在同一台主机上的时候,connect回马上结束,并返回0;无需等待。

 

ret = connect(sock[i],(struct sockaddr *)&tracker[i],
				          sizeof(struct sockaddr));
if(ret < 0 && errno != EINPROGRESS)  valid[i] = 0;

 

EINPROGRESS

The socket is non-blocking, and the connection cannot be completed immediately. You can use select(3C) to complete the connection by selecting the socket for writing.

 

 

过调用 getsockopt(sockfd,SOL_SOCKET,SO_ERROR,&error,&len); 函数返回值来判断是否发生错误

int error, len;

error = 0;

len = sizeof(error);

if(getsockopt(sock[i],SOL_SOCKET,SO_ERROR,&error,&len) < 0) {

valid[i] = 0;

close(sock[i]);

}

error返回0则表示连接成功!

 

 

分享到:
评论

相关推荐

    linux客户端Socket非阻塞connect编程[归纳].pdf

    linux客户端Socket非阻塞connect编程[归纳].pdf

    linux客户端Socket非阻塞connect编程收集.pdf

    linux客户端Socket非阻塞connect编程收集.pdf

    QTcpSocket通信编程时阻塞与非阻塞的问题 - findumars - 博客园1

    1. 编程理解(36) 1. 经典资料(15) 1. 开源项目(16) 9.SaaS-云存储,云服务(38) 9.SaaS-云计算-学习(38)

    windows下设置socket的connect超时

    2.将该socket设置为非阻塞模式 3.调用connect() 4.使用select()检查该socket描述符是否可写(注意,是可写) 5.根据select()返回的结果判断connect()结果 6.将socket设置为阻塞模式(如果你的程序不需要用阻塞...

    MFC网络编程之自制浏览器

    网络编程,当然要用到Windows Socket(套接字)技术。Socket相关的操作由一系列...因此,建议初学者学习编网络通信程序时,暂且不要用MFC提供的类,而先用Winsock2 API,这样有助于对异步、非阻塞Socket编程机制的理解。

    socket编程中select的使用

    可是使用 Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不 同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件...

    linux网络编程-宋敬彬-part1

    9.6 非阻塞编程 264 9.6.1 非阻塞方式程序设计介绍 264 9.6.2 非阻塞程序设计的例子 264 9.7 小结 266 第10章 基于UDP协议的接收和发送 267 10.1 UDP编程框架 267 10.1.1 UDP编程框图 267

    ts-postgres:用TypeScript编写的Node.js的非阻塞PostgreSQL客户端

    ts-postgres 用TypeScript编写的Node.js的非阻塞PostgreSQL客户端。安装要安装此库的最新版本: $ npm install ts-postgres@latest特征快速地! 支持二进制和文本值格式结果数据当前仅以二进制格式发送可以一次发送...

    Linux高性能服务器编程

    9.2 poll系统调用 9.3 epoll系列系统调用 9.3.1 内核事件表 9.3.2 epoll_wait函数 9.3.3 LT和ET模式 9.3.4 EPOLLONESHOT事件 9.4 三组IO复用函数的比较 9.5 IO复用的高级应用一:非阻塞connect 9.6 IO复用...

    TcpScan(Console&MFC)

    里面分为两个程序,一个是Console下面的,一个是MFC的,其中Console中socket是阻塞select模式,MFC下面的是WSAAsyncSelect异步非阻塞模式。 都是利用Tcp Connect扫描端口,都可以批量ip,批量端口扫描,都是多线程的...

    oauth.apisample.javaspringboot:使用OAuth和Open Id Connect的最终Java API代码示例

    oauth.apisample.javaspringboot概述使用OAuth和Open Id... AWS Cognito用作默认授权服务器用于实现OAuth自定义过滤器用于通过简单的代码实现非阻塞API 可以将API日志汇总到以支持SSL证书certs文件夹中的证书源自存储库

    linux 网络编程源代码

    第一章 概论 ..................................................................................................................1 1.1 网络的历史.............................................................

    Linux网络编程

    6.10.2 非阻塞模式I/O.... 180 6.10.3 I/O 多路复用.... 181 6.10.4 信号驱动I/O 模式........... 182 6.10.5 异步I/O 模式... 185 6.10.6 几种I/O 模式的比较........ 186 6.10.7 fcntl()函数........ 186 6.10.8 ...

    linux网络编程学习笔记

    UDP(User Datagram Protocol)用户数据报协议是一种非面向连接的协议,这种协议并不能保证 我们的网络程序的连接是可靠的,所以我们现在编写的程序一般是采用 TCP协议的 socket int socket(int domain, int type,...

    linux网路编程 中文 23M 版

    第2 章Linux编程环境....................................................................................................14 2.1 Linux环境下的编辑器................................................. 14 ...

    linux 下socket通信中select的用法实例

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

    Linux网络编程.pdf socket tcp udp

    第一章 概论 .................................................................................................................. 1 1.1 网络的历史...........................................................

    Windows内核安全与驱动开发光盘源码

    5.3 阻塞、等待与安全设计 80 5.3.1 驱动主动通知应用 80 5.3.2 通信接口的测试 81 5.3.3 内核中的缓冲区链表结构 83 5.3.4 输入:内核中的请求处理中的安全检查 84 5.3.5 输出处理与卸载清理 85 第6章 64位和...

Global site tag (gtag.js) - Google Analytics