步骤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. 数据可视化-使用EXCEL和PS制作一个复杂饼图

    一个朋友让我帮忙用饼图去展现一下一堆数据,我说行,后来他给我后,我看到是一堆貌似从什么仪器中导出的一堆使用分隔符分开的文本文档,使用excel打开后如下(为了保护隐私忽略了用字母和数字代替原来的内容: ...

  2. C语言-if语句

    1.一般形式 if(表达式)表达式1 else 表达式2   :表达式成立(为真)则执行表达式1,否则执行表达式2. 适用范围:真假,对错,开关,对立面的条件 注意:如果if语句中只包括一条语句,可以 ...

  3. thinkPHP的学习

    1.版本,以3.1为主,因为手册是基于这个的,最新的版本,还没有对应的手册 2.发现一个问题,echo 中文时,出现乱码,而调用模版则正常. 3.写url的注意大小写.index和Index是不同的 ...

  4. PHP 魔术变量和魔术函数详解

    魔术变量 PHP 向它运行的任何脚本提供了大量的预定义常量. 不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了. 有八个魔术常量它们的 ...

  5. Objective-C中的Hello World

    Objective-C在C语言的基础之上,加入了自己的一些独特的特性,而且在Objective-C中兼容C语言原有的用法.在Objective-C中,实现Hello World和C语言有一定的区别,如 ...

  6. systemd学习

    http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html http://www.ruanyifeng.com/blog ...

  7. 利用DIV+CSS制作网页过程中常用的基本概念及标签使用细节

    CSS主要用于对HTML文件功能的补充及扩展,其作用就是对HTML文件中各种排版进行设置,达到对网页中字体.颜色.背景.图片等的控制,使网页能够完全依照设计者的想法来显示. CSS可以控制网页的显示, ...

  8. UED大全

    http://www.baiduux.com/  百度UFOhttp://ued.sohu.com/  搜狐UEDhttp://ued.taobao.com/  淘宝UEDhttp://www.ued ...

  9. JSON数据格式中的引号

    JSON数据中必须使用双引号: $.getJSON,的输入必须是正确的JSON数据,否则不会执行回调函数: $.parseJSON的输入必须是正确的JSON数据,否则会有异常:

  10. PHP上传图片重命名6种方案

    一. 适用场景:无法使用从数据库中返回的自增长数字,给上传图片重命名.这是图片或文件上传的流程决定的.一般图片上传处理过程是,先上传图片到服务器,重命名之后,插入到数据库.也就是说,在数据库中非常容易 ...