llinux epoll系列4 利用epoll_wait实现非阻塞的connect

connect函数是阻塞的,而且不能设置connect函数的timeout时间,所以一旦阻塞太长时间,影响用户的体验,所以就出来一个需求,硬要设置connect的timeout时间。

实现方法:先把connect函数变成非阻塞的,然后用设置epoll_wait的timeout时间,用epoll_wait等待connect的完成。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <arpa/inet.h>
#include <fcntl.h> #define EVENTS 10 int main(){
sockaddr_in server;
int sock, epfd;
char buf[32];
int nfds, n;
int val;
epoll_event ev, ev_ret[EVENTS]; sock = socket(AF_INET, SOCK_STREAM, 0); server.sin_family = AF_INET;
server.sin_port = htons(12345);
inet_pton(AF_INET, "127.0.0.1", &server.sin_addr.s_addr); epfd = epoll_create(1);
if(epfd < 0){
perror("epfd");
return 1;
} memset(&ev, 0, sizeof(ev));
ev.events = EPOLLIN;
ev.data.fd = sock; if(epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev) != 0){
perror("epoll_ctl");
return 1;
} val = 1;
//本来下面的connect函数是阻塞的,但是用FIONBIO的ioctl函数后,就变成非阻塞的了,
//所以不管connect函数成功与否,都立即结束了。
ioctl(sock, FIONBIO, &val); n = connect(sock, (sockaddr*)&server, sizeof(server)); if(n != 0){
if(errno == EINPROGRESS){
printf("before epoll_wait\n"); nfds = epoll_wait(epfd, ev_ret, EVENTS, 1000*10);//timeout is 1 sec
if(nfds < 0){
perror("epoll_wait\n");
return 1;
}
printf("after epoll_wait : nfds=%d\n", nfds);
}
else{
perror("connect");
return 1;
}
} n = read(sock, buf, sizeof(buf));
write(fileno(stdout), buf, n); close(sock); return 0; }

github源代码

但是,虽然成功的让connect函数变成了非阻塞的了,但是也让epoll_wait函数也变成非阻塞的,不管怎么设置epoll_wait的timeout,都不起作用,程序瞬间的完成。求高人指点!!!!

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ llinux epoll系列4 利用epoll_wait实现非阻塞的connect的更多相关文章

  1. c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度

    linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...

  2. c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信

    linux epoll系列2 利用epoll_wait查看是否可以送信 write函数本来是非阻塞函数,但是当缓存区被写满后,再往缓存区里写的时候,就必须等待缓存区再次变成可写,所以这是write就变 ...

  3. c/c++ llinux epoll系列5 解除epoll_wait状态

    linux epoll系列5 解除epoll_wait状态 有时候会有解除epoll_wait状态的需求. 实现方法: 1,给执行epoll_wait的程序发signal. 2,使用sockpair. ...

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

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

  5. UNIX网络编程——epoll 系列函数简介、与select、poll 的区别

    前面博客<<UNIX环境高级编程--epoll函数使用详解>>有关于epoll函数的讲解. 一.epoll 系列函数简介 #include <sys/epoll.h> ...

  6. c/c++ linux epoll系列1 创建epoll

    linux epoll系列1 创建epoll 据说select和poll的弱点是,随着连接(socket)的增加,性能会直线下降. epoll不会随着连接(socket)的增加,性能直线下降. 知识点 ...

  7. epoll 系列函数简介、与select、poll 的区别

    一.epoll 系列函数简介 #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags) ...

  8. IO复用——epoll系列系统调用

    1.内核事件表 epoll是Linux特有的I/O复用函数.epoll把用户关心的文件描述上的事件放在内核里的一个事件表中,并用一个额外的文件描述符来标识该内核事件表.这个额外文件描述符使用函数epo ...

  9. IO复用之epoll系列

    epoll是什么? epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的 ...

随机推荐

  1. [bzoj4771] 七彩树

    题意 给定一棵n个点,每个点带颜色的有根树.点的编号和颜色编号都在1到n,根的编号为1.m次询问,求x子树中与x距离边数不超过k的点中,颜色的种类数目.每个测试点有多组数据. 分析 不妨设1的父亲为0 ...

  2. scala读取配置文件

    Class: package libparser import scala.collection.mutable import scala.util.matching.Regex class conf ...

  3. 死磕 java集合之TreeMap源码分析(二)- 内含红黑树分析全过程

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 插入元素 插入元素,如果元素在树中存在,则替换value:如果元素不存在,则插入到对应的位置, ...

  4. 死磕 java集合之HashMap源码分析

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 HashMap采用key/value存储结构,每个key对应唯一的value,查询和修改 ...

  5. AttributeError: module 'pip' has no attribute 'main'

    Pycharm在运行pip安装模块是报错如下: 解决方法: 找到安装路径下的packaging_tool.py文件修改如下: 我的路径为D:\Program Files\JetBrains\PyCha ...

  6. HttpClientFactory与Steeltoe结合来完成服务发现

    前言 上一篇说了一下用HttpClientFactory实现了简单的熔断降级. 这篇就来简单说说用HttpClientFactory来实现服务发现.由于标题已经好明显的说了Steeltoe 因此这里会 ...

  7. js内存深入学习(二)

    继上一篇文章 js内存深入学习(一) 3. 内存泄漏 对于持续运行的服务进程(daemon),必须及时释放不再用到的内存.否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃. 对于不再用到的内 ...

  8. python迭代和解析(3):range、map、zip、filter和reduce函数

    解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html range range()是一个内置函数,它返回一个数字序列,功能和Li ...

  9. 开源分布式数据库SequoiaDB在去哪儿网的实践

    编者注: 中国的数据库行业也迎来了一波新的热点事件.分布式数据库这块新消息不断,也让大家开始关注中国的分布式数据库.首先是短短一周内,Pingcap和SequoiaDB巨杉数据库陆续宣布了C轮的数千万 ...

  10. C#简单接口和继承示例详解——快速入门

    上一篇中我们说到继承,其实他们之间是差不多的. 接口是方法的抽象,如果不同的类有同样的方法,那么就应该考虑使用接口. C#中接口可以多继承,接口之间可以相互继承和多继承.一个类可以同时继承一个类和多个 ...