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. [Abp 源码分析]二、模块系统

    0.简介 整个 Abp 框架由各个模块组成,基本上可以看做一个程序集一个模块,不排除一个程序集有多个模块的可能性.可以看看他官方的这些扩展库: 可以看到每个项目文件下面都会有一个 xxxModule ...

  2. 13.Django1.11.6文档

    第一步 入门 检查版本 python -m django --version 创建第一个项目 django-admin startproject mysite 运行 python manage.py ...

  3. Dockerfile指令介绍

    FROM:指定基础镜像 在Dockerfile中FROM是必备的指令,用于指定基础的镜像. FROM centos:latest LABEL:指定镜像标签 LABEL指令用来指定镜像的标签. 格式: ...

  4. log4cplus使用(二)-自定义日志等级

    log4cplus支持用户自定义日志等级,操作也比较简单,使用之前贴如下宏定义 #define LOG4CPLUS_MACRO_CREASH_LOG_LEVEL(pred) LOG4CPLUS_UNL ...

  5. 微信小程序与AspNetCore SignalR聊天实例

    微信小程序与aspnetcore signalr实例 本文不对小程序与signalr做任何介绍,默认读者已经掌握 aspnetcore Signalr文档 小程序文档 写在之前 SignalR没有提供 ...

  6. 初学Java Web(2)——搭建Java Web开发环境

    虽然说 html 和 css 等前端技术,是对于 Web 来说不可或缺的技术,但是毕竟更为简单一些,所以就不详细介绍了,没有基础的同学可以去菜鸟教程或者W3school进行自主学习,最好的方式还是做一 ...

  7. Linux - CentOS 登陆密码找回解决方法

  8. man帮助文档打印

    这里不讨论大家都知道的man重定向的一般常用方法(col处理方法)$ man find | col -b > man_fine.txt [跟着我的思路走]假如您像我一样,直接使用如下命令导出fi ...

  9. Java开发知识之Java编程基础

    Java开发知识之Java编程基础 一丶Java的基础语法 每个语言都有自己的语法规范.例如C++ 入口点是main. 我们按照特定格式编写即可. Java也不例外. Java程序的语法规范就是 Ja ...

  10. docker删除镜像和删除容器

    删除容器:docker rm ID 删除镜像:docker rmi ID