步骤1: 设置非阻塞,启动连接
实现非阻塞 connect ,首先把 sockfd 设置成非阻塞的。这样调用
connect 可以立刻返回,根据返回值和 errno 处理三种情况:
() 如果返回 ,表示 connect 成功。
() 如果返回值小于 , errno 为 EINPROGRESS, 表示连接
建立已经启动但是尚未完成。这是期望的结果,不是真正的错误。
() 如果返回值小于0,errno 不是 EINPROGRESS,则连接出错了。 步骤2:判断可读和可写
然后把 sockfd 加入 select 的读写监听集合,通过 select 判断 sockfd
是否可写,处理三种情况:
() 如果连接建立好了,对方没有数据到达,那么 sockfd 是可写的
() 如果在 select 之前,连接就建立好了,而且对方的数据已到达,
那么 sockfd 是可读和可写的。
() 如果连接发生错误,sockfd 也是可读和可写的。
判断 connect 是否成功,就得区别 () 和 (),这两种情况下 sockfd 都是
可读和可写的,区分的方法是,调用 getsockopt 检查是否出错。 步骤3:使用 getsockopt 函数检查错误
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len)
在 sockfd 都是可读和可写的情况下,我们使用 getsockopt 来检查连接
是否出错。但这里有一个可移植性的问题。
如果发生错误,getsockopt 源自 Berkeley 的实现将在变量 error 中
返回错误,getsockopt 本身返回0;然而 Solaris 却让 getsockopt 返回 -,
并把错误保存在 errno 变量中。所以在判断是否有错误的时候,要处理
这两种情况。 代码: C代码 收藏代码
int conn_nonb(int sockfd, const struct sockaddr_in *saptr, socklen_t salen, int nsec)
{
int flags, n, error, code;
socklen_t len;
fd_set wset;
struct timeval tval; flags = fcntl(sockfd, F_GETFL, );
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); error = ;
if ((n == connect(sockfd, saptr, salen)) == ) {
goto done;
} else if (n < && errno != EINPROGRESS){
return (-);
} /* Do whatever we want while the connect is taking place */ FD_ZERO(&wset);
FD_SET(sockfd, &wset);
tval.tv_sec = nsec;
tval.tv_usec = ; if ((n = select(sockfd+, NULL, &wset,
NULL, nsec ? &tval : NULL)) == ) {
close(sockfd); /* timeout */
errno = ETIMEDOUT;
return (-);
} if (FD_ISSET(sockfd, &wset)) {
len = sizeof(error);
code = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);
/* 如果发生错误,Solaris实现的getsockopt返回-1,
* 把pending error设置给errno. Berkeley实现的
* getsockopt返回0, pending error返回给error.
* 我们需要处理这两种情况 */
if (code < || error) {
close(sockfd);
if (error)
errno = error;
return (-);
}
} else {
fprintf(stderr, "select error: sockfd not set");
exit();
} done:
fcntl(sockfd, F_SETFL, flags); /* restore file status flags */
return ();
}

非阻塞connect的更多相关文章

  1. UNIX网络编程-非阻塞connect和非阻塞accept

    1.非阻塞connect 在看了很多资料之后,我自己的理解是:在socket发起一次连接的时候,这个过程需要一段时间来将三次握手的过程走完,如果在网络状况不好或者是其他的一些情况下,这个过程需要比较长 ...

  2. linux 客户端 Socket 非阻塞connect编程

    开发测试环境:虚拟机CentOS,windows网络调试助手        非阻塞模式有3种用途        1.三次握手同时做其他的处理.connect要花一个往返时间完成,从几毫秒的局域网到几百 ...

  3. TCP非阻塞accept和非阻塞connect

    http://blog.chinaunix.net/uid-20751538-id-238260.html 非阻塞accept     当一个已完成的连接准备好被accept的时候,select会把监 ...

  4. 面向连接的socket数据处理过程以及非阻塞connect问题

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

  5. UNIX网络编程——非阻塞connect: Web客户程序

    非阻塞的connect的实现例子出自Netscape的Web客户程序.客户先建立一个与某个Web服务器的HTTP连接,再获取一个主页.该主页往往含有多个对于其他网页的引用.客户可以使用非阻塞conne ...

  6. UNIX网络编程——非阻塞connect:时间获取客户程序

    #include "unp.h" int connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) ...

  7. UNIX网络编程——非阻塞connect

    当在一个非阻塞的TCP套接字上调用connect时,connect将立即返回一个EINPROGRESS错误,不过已经发起的TCP三次握手继续进行.我们接着使用select检测这个连接或成功或失败的已建 ...

  8. 网络编程之非阻塞connect编写

    一.connect非阻塞编写 TCP连接的建立涉及到一个三次握手的过程,且socket中connect函数需要一直等到客户接收到对于自己的SYN的ACK为止才返回, 这意味着每 个connect函数总 ...

  9. 由select/epoll返回的非阻塞connect还会是EINPROGRESS状态吗?

    一般情况下,我们像下面代码中所示的这样使用非阻塞connect: #include <stdio.h> #include <stdlib.h> #include <str ...

随机推荐

  1. IOS9新特性之Contacts联系人

    在以前iOS开发中,涉及联系人相关的编程,代码都非常繁琐,并且框架的设计也不是Objective-C风格的,这使开发者用起来非常的难受.在iOS9中,apple终于解决了这个问题,全新的Contact ...

  2. C语言-结构体

    C语言中数组是把相同类型的数据类型的变量集中在一起了,而结构体则是把不同类型的变量聚集在一起. 结构体也是一种数据类型,但是它是一种自定义的数据类型,也就是说和使用其他数据类型不一样,我们得先定义这种 ...

  3. iOS 之 内存管理

    凡是alloc copy mutablecopy init 声明的变量,都需要通过手动的方式进行释放,realse. 如果 copy一个对象,则拥有了拷贝的对象,要负责释放. 如果 保持(retain ...

  4. Java经典案例之-“成绩等级划分”

    /** * 描述:在对话框中输入学习成绩,利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示, * 60分以下的用C表示. * 分析:可以利用三目运算符 ...

  5. 记一次DG搭建过程中ORA-09925: Unable to createaudit trail file 错误

    今天做Oracle DG  编写initorcl的时候,修改完以后,sqlplus就不能再登陆,一直报 ERROR: ORA-09925: Unable to createaudit trail fi ...

  6. eclipse xml自动提示

    找到所需要的dtd文件: window->preferences->xml->xml catalog : public id 输入对应的字符串:

  7. js运算符单竖杠“|”的作用

    在js整数操作的时候,相当于去除小数点,parseInt.在正数的时候相当于Math.floor(),负数的时候相当于Math.ceil() 注: 1. Math.ceil()用作向上取整. 2. M ...

  8. SDWebImage源码解读之SDWebImagePrefetcher

    > 第十篇 ## 前言 我们先看看`SDWebImage`主文件的组成模块: ![](http://images2015.cnblogs.com/blog/637318/201701/63731 ...

  9. HTML5本地存储 localStorage 和 sessionStorage 的基本用法及属性

    localStorage 和 sessionStorage 的用法都是本地的存储和获取 但他们又有所区别, 1, sessionStorage 是一个短暂的本地存数,它会随着浏览器的刷新和关闭而消失, ...

  10. 2016 ACM/ICPC Asia Regional Qingdao Online(2016ACM青岛网络赛部分题解)

    2016 ACM/ICPC Asia Regional Qingdao Online(部分题解) 5878---I Count Two Three http://acm.hdu.edu.cn/show ...