一般情况下,我们像下面代码中所示的这样使用非阻塞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. 玩转rocketMQ

    下载地址https://github.com/alibaba/RocketMQ 安装环境需要jdk,maven,git http://maven.apache.org/download.html

  2. JSON.parse()和jQuery.parseJSON()的区别

    jQuery.parseJSON(jsonString) : 将格式完好的JSON字符串转为与之对应的JavaScript对象   (jquery 方法) 1 2 3 var str = '[{&qu ...

  3. [SQLite] SQLite学习手册(数据库和事务)

    转载地址:http://www.cnblogs.com/stephen-liu74/archive/2012/02/18/2322575.html 一.Attach数据库: ATTACH DATABA ...

  4. 解决Ubuntu下的Eclipse打开Windows编写的java代码的中文乱码

    其实所有的中文乱码 问题都是编码不同所导致的.这里要想让eclipse能正常显示出汉字,就要修改它的字符编码 步骤如下: 1 ,点击菜单栏中的Window(窗口),选择Preferences(首选项) ...

  5. (转)AssetBundle系列——游戏资源打包(一)

    转自:http://www.cnblogs.com/sifenkesi/p/3557231.html 将本地资源打包,然后放到资源服务器上供游戏客户端下载或更新.服务器上包含以下资源列表:(1)游戏内 ...

  6. 微信小程序:字体保持大小

    小程序和网页差不多,前台用wxml把内容摆好,然后用css调整样式.所以和web一样,必须要能够精确控制每一个元素的大小.在Web中,通过CSS基本达到了像素级的控制.但在小程序中,情况有所不同.下面 ...

  7. [Algorithm] Print All Subsets of a Set

    Let's say given a number of array, you should print out, all the subet of this array. Example: [1, 2 ...

  8. linux下如何查看所有的用户和组信息?

    /etc/group  文件是用户组的配置文件. /etc/passwd 文件是用户的配置文件. 使用cat.more.less.head.tail以及vim等命令都可以查看.修改这两个配置文件. 说 ...

  9. (排序)快速排序QuickSort

    主要内容: 1.算法思想 2.快速排序算法 3.划分算法partition 4.快排过程图解 5.完整代码 1.算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一 ...

  10. ubuntu apache2 虚拟主机服务

    ubuntu apache2 虚拟主机服务 本次配置的是一个 ip 对应多个 虚拟主机 1:先检查 ubuntu server 是否已经安装了 apache2 web服务: apache2 -v 看到 ...