步骤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. zend framework 1.10项目配置与经典hello world

    准备工作 前置条件:PHP>=5.14,Apache开启mod_rewrite支持,开启php的pdo扩展. Zend Framework 要求 PHP版本不低于5.1.4,但强烈建议使用 5. ...

  2. ECSHOP中ajax的调用原理

    ECSHOP中ajax的调用原理 ecshop中ajax的调用原理. 1.首先ecshop是如何定义ajax对象的. ecshop中的ajax对象是在js/transport.js文件中定义的.里面是 ...

  3. UVa 11308 - Bankrupt Baker

    题目大意:给出一些原料和价钱和若干份菜谱,每份菜谱都标明所需的原料和数量,找出所有不超过预算的菜谱. 没什么好说的,主要是对map的运用. #include <cstdio> #inclu ...

  4. JVM面试

    深入理解Java内存模型:http://www.cnblogs.com/skywang12345/p/3447546.html http://www.infoq.com/cn/articles/jav ...

  5. Android studio的那些bug

    R文件无法编译: 1.Activity继承类AppCompatActivity有时候会报错 2.R文件找不到一般是layout文件夹下出错 3.sdk包问题 4.Gradle DSL method n ...

  6. Zju1290 Word-Search Wonder(http://begin.lydsy.com/JudgeOnline/problem.php?id=2768)

    2768: Zju1290 Word-Search Wonder Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 4  Solved: 2[Submit] ...

  7. div垂直居中(js)

    window.onload = function(){ var xx = document.documentElement.clientHeight; // 470为要垂直居中的div的高度 he = ...

  8. IOC容器Unity的使用及独立配置文件Unity.Config

    [本段摘录自:IOC容器Unity 使用http://blog.csdn.net/gdjlc/article/details/8695266] 面向接口实现有很多好处,可以提供不同灵活的子类实现,增加 ...

  9. ubuntu系统中crontab的使用介绍

    1.创建crontab任务 用户hancool

  10. Add Strings Leetcode

    Given two non-negative integers num1 and num2 represented as string, return the sum of num1 and num2 ...