一般情况下,我们像下面代码中所示的这样使用非阻塞connect:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <errno.h> #define EPOLL_MAXEVENTS 64 int main(int argc, char *argv[])
{
int fd, epfd, flags, status, ret, nevents, i, slen;
struct sockaddr_in addr;
struct in_addr remote_ip;
struct epoll_event ev, events[EPOLL_MAXEVENTS];; if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
perror("socket failed");
return -1;
} status = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int))) {
perror("setsockopt failed");
return -1;
} flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK); memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = 9999;
if (inet_pton(AF_INET, "10.232.129.43", &addr.sin_addr) <= 0) {
perror("inet_pton error");
return -1;
} ret = connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr));
if (ret == 0) {
printf("non-blocking connect success. connect complete immediately");
close(fd);
return -1;
} if (ret < 0 && errno != EINPROGRESS) {
perror("connect error!");
return -1;
} epfd = epoll_create(EPOLL_MAXEVENTS);
ev.events = EPOLLOUT;
ev.data.fd = fd;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1 ) {
perror("epoll_ctl error");
goto finish;
}
printf("add connect fd into epoll"); memset(events, 0, sizeof(events)); for (;;) { nevents = epoll_wait(epfd, events, EPOLL_MAXEVENTS, -1); if (nevents < 0) {
perror("epoll_wait failed");
goto finish;
} for (i = 0; i < nevents; i++) { if (events[i].data.fd == fd) { if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen)
< 0)
{
perror("getsockopt error!");
goto finish;
}
if (status != 0) {
perror("connect error!");
goto finish;
} printf("non-blocking connect success!"); if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) == -1 ) {
perror("epoll_ctl error");
return 0;
} /* DO write... */
}
}
} finish:
close(fd);
close(epfd); return 0;
}

  在上面的代码中需要注意几点:

1,什么时候connect返回成功?

三次握手中的client如果收到server对SYN的ACK,connect就会返回。

2,非阻塞的connect成功返回后,用getsockopt获得的SO_ERROR码还会使EINPROGRESS吗?

不会。除非是epoll设置的超时时间到达,否则epoll_wait返回fd后,表明fd已经可写,connect已经建立成功。此时如果getsockopt获取到的SO_ERROR 状态码是status表明connect已失败,不可能再是EINPROGRESS。

由select/epoll返回的非阻塞connect还会是EINPROGRESS状态吗?的更多相关文章

  1. (转)非阻塞Connect对于select时应注意问题

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

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

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

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

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

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

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

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

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

  6. 非阻塞connect

    步骤1: 设置非阻塞,启动连接 实现非阻塞 connect ,首先把 sockfd 设置成非阻塞的.这样调用 connect 可以立刻返回,根据返回值和 errno 处理三种情况: () 如果返回 , ...

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

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

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

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

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

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

随机推荐

  1. Derby设置密码教程

    方法一:    配置derby.propertites文件: 文件内容: derby.connection.requireAuthentication=truederby.authentication ...

  2. 分割流 SequenceInputStream (转)

    import java.io.*;import java.util.*; class SplitFile{ public static void main(String[] args) throws ...

  3. mysqld_safe脚本执行的基本流程

    mysqld_safe脚本执行的基本流程:1.查找basedir和ledir.2.查找datadir和my.cnf.3.对my.cnf做一些检查,具体检查哪些选项请看附件中的注释.4.解析my.cnf ...

  4. MyBatis使用Collection查询多对多或一对多结果集bug

    情况描述:当使用JOIN查询,如果SQL查询出来的记录不是按id列排序的,则生成的List结果会有问题 案例: 1) 数据库模型 简而言之一个Goods包含多个Goods_Img 2) Java Be ...

  5. iOS:UITableView表格视图控件

    UITableView:表格视图控件,继承滚动视图控件UIScrollView,(类似于UIPickerView选择器,它主要通过设置数据源代理和行为代理实现协议来设置单元格)    对表格的操作主要 ...

  6. OpenCV学习(22) opencv中使用kmeans算法

    kmeans算法的原理参考:http://www.cnblogs.com/mikewolf2002/p/3368118.html 下面学习一下opencv中kmeans函数的使用.      首先我们 ...

  7. 3D屏保:排色榜

    3D屏保:排色榜 排色榜,是一个针对图形学中的色彩进行排序的DEMO,这里的色是色彩的意思,看成别的点进来的同学请自觉面壁.该DEMO可以按RGB,GBR,BRG,灰度值四种方式进行排序.排序算法为冒 ...

  8. 以ScaleIO 1.30为后端存储运行微软服务器软件SQL Server 2014, SharePoint 2013, Exchange 2013的解决方案

    EMC新发布了以ScaleIO 1.30为后端存储来运行SQL, SharePoint, Exchange的解决方案白皮书.   下面的页面中有简要的介绍和整篇文档PDF的下载. https://co ...

  9. C#异常处理及心得

    C sharp中的异常用于处理系统级和应用程序级的错误状态,它是一种结构化.统一的类型安全的处理机制.c#的异常 机制非常类似于c++的异常处理机制,但是还是有一些重要的区别: 1,在 C# 中,所有 ...

  10. (剑指Offer)面试题60:把二叉树打印成多行

    题目: 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 思路: 很明显,采用广度优先遍历来解决,但因为需要按行输出,所以需要判断每一层的开始和结束,因此需要两个变量,一个表示当前层尚 ...