Linux非阻塞IO(四)非阻塞IO中connect的实现
我们为客户端的编写再做一些工作。
这次我们使用非阻塞IO实现connect函数。
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
非阻塞IO有以下用处:
1.将三次握手的处理过程生下来,处理其他事情。
2.使用这个同时建立多个连接。
3.实现超时connect功能,本节实现的connect就可以指定时间,超时后算作错误处理。
在阻塞IO中,调用connect后一般会阻塞,直到确定连接成功或者失败。
在Non-Blocking IO中,connect往往会立刻返回,此时connect就有两种结果。
一是连接成功
二是返回-1,errno置为EINPROGRESS,这种一般是因为网络延迟,所以连接不能马上建立,我们需要使用poll来监听sockfd。
所以接下来我们需要向poll注册sockfd的写事件。
《TCP/IP详解》第二卷指出以下的一些规则:
当连接建立时,sockfd可写。
当遇到错误时,sockfd既可读又可写。
我们设置一个超时时间,当poll返回时,如果sockfd可写,此时有两种情况:
一是连接确实建立成功
二是连接发生错误
我们需要某些手段辨别究竟是否发生了错误。
这里我们采用socket选项,检测的是SO_ERROR,代码如下:
int get_sockfd_error(int sockfd)
{
int err;
socklen_t socklen = sizeof(err);
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &socklen) == -1)
ERR_EXIT("getsock_error error");
if (err == 0)
return 0; //无错误
else
return err;
}
如果sockfd无错误,则返回0,否则返回错误代码。
在非阻塞connect的实现中,我们通常需要先把fd设置为非阻塞,最后再重新设置为阻塞。这样做,是为了满足阻塞与非阻塞的需求。
因为在阻塞IO中,有时候也会使用非阻塞connect。
实现代码如下:
int nonblocking_connect(int sockfd, const char *des_host, uint16_t des_port, int timeout)
{
if(des_host == NULL)
{
fprintf(stderr, "des_host can not be NULL\n");
exit(EXIT_FAILURE);
} SAI servaddr;
memset(&servaddr, 0, sizeof servaddr);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(des_port);
if(inet_aton(des_host, &servaddr.sin_addr) == 0)
{
//DNS
//struct hostent *gethostbyname(const char *name);
struct hostent *hp = gethostbyname(des_host);
if(hp == NULL)
ERR_EXIT("gethostbyname");
servaddr.sin_addr = *(struct in_addr*)hp->h_addr;
} //设置为非阻塞
activate_nonblock(sockfd); //connect会立刻返回
int ret = connect(sockfd, (SA*)&servaddr, sizeof servaddr);
if(ret == -1)
{
if(errno != EINPROGRESS) //连接失败
ERR_EXIT("connect error");
struct pollfd pfd[1];
pfd[0].fd = sockfd;
pfd[0].events = POLLOUT; ret = poll(pfd, 1, timeout); if(ret == 0)
{
errno = ETIMEDOUT;
ret = -1; //连接超时,此时判定为失败
}
//sockfd可写,此时需要检查套接字选项,查看是否发生错误
else if(ret == 1 && pfd[0].revents & (POLLOUT | POLLWRBAND))
{
int err;
//检查sockfd错误
if((err = get_sockfd_error(sockfd)))
{
errno = err;
return -1;
}
}
} //重新设置为阻塞
deactivate_nonblock(sockfd);
return ret;
}
读者可以自行测试。
下节使用非阻塞connect实现客户端。
Linux非阻塞IO(四)非阻塞IO中connect的实现的更多相关文章
- linux select 与 阻塞( blocking ) 及非阻塞 (non blocking)实现io多路复用的示例
除了自己实现之外,还有个c语言写的基于事件的开源网络库:libevent http://www.cnblogs.com/Anker/p/3265058.html 最简单的select示例: #incl ...
- linux select 与 阻塞( blocking ) 及非阻塞 (non blocking)实现io多路复用的示例【转】
转自:https://www.cnblogs.com/welhzh/p/4950341.html 除了自己实现之外,还有个c语言写的基于事件的开源网络库:libevent http://www.cnb ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- Linux IO模式-阻塞io、非阻塞io、多路复用io
一 概念说明 在进行解释之前,首先要说明几个概念: - 用户空间和内核空间 - 进程切换 - 进程的阻塞 - 文件描述符 - 缓存 I/O 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对3 ...
- 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型
1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...
- Linux中同步与异步、阻塞与非阻塞概念以及五种IO模型
1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...
- Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO
背景 整理之前学习socket编程的时候复习到了多路复用,搜索了有关资料,了解到多路复用也有局限性,本着打破砂锅问到底的精神,最终找到了关于IO模型的知识点. 在<Unix网络编程>一书中 ...
- Linux IO 同步/异步 阻塞/非阻塞
同步IO:导致请求进程阻塞,直到IO操作完成: 是内核通知我们何时进行启动IO操作,而实际的IO操作需要当前进程本身阻塞完成: 包括:阻塞式IO模型,非阻塞式IO模型,IO复用模型,信号驱动式IO模型 ...
- 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...
- 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...
随机推荐
- 由做网站操作日志想到的HttpModule应用
背景 在以前的Web项目中,记录用户操作日志,总是在方法里,加一行代码,记录此时用户操作类型与相关信息.该记录日志的方法对原来的业务操作侵入性较强,也比较零散,不便于查看和管理.那么有没有更加通用点的 ...
- eclipse 调试(debug) burpsuite 插件(Extender)
demo: https://github.com/src-kun/transparent-cap/tree/master/burpsuite 1.打开demo项目: 2.右键项目点击Configure ...
- vue-cli 3.0脚手架与vux的配合使用
在最近的项目中,引用了vux,在可拓展性以及复用性,都算是比较优秀的框架了.但是美中不足的是对于vux在对于vue-cli3.0的跟进还没有同步 需要自己做下修改,同比 有赞的vant 以及 ivie ...
- Selenium2+python自动化17-JS处理滚动条【转载】
前言 selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了. 常见场景: 当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的. 这时候 ...
- object的hashCode与equals
JAVA代码: public static void main(String[] args) { Object obj1 = new Object(); Obj ...
- 扫面线+线段树(hdu1542)
之前写过这个算法,时间长了就忘掉了,,现在不看书自己努力回想起来,对算法的理解,对线段树的理解感觉也更深了一点(可能心理作用,哈哈哈) 思路简单说一下吧 从做到右遍历每一条矩阵的边(左右边),看该边对 ...
- adb 查看android手机中应用的包名和安装位置
1. 查看是否连接手机 adb devices 2. 进入指定的device的shell adb shell 或者 adb -s ********* shell 3. adb 查看所有安装的包 pm ...
- [BZOJ 1800] 飞行棋
Link: BZOJ 1800 传送门 Solution: $O(n^4)$…… Code: #include <bits/stdc++.h> using namespace std; ] ...
- php升级版本
Centos下Yum安装PHP5.5,5.6,7.0 默认的版本太低了,手动安装有一些麻烦,想采用Yum安装的可以使用下面的方案: 1.检查当前安装的PHP包 yum list installed | ...
- 八. 输入输出(IO)操作3.面向字符的输出流
面向字符的输出流都是类 Writer 的子类,其类层次结构如图 10-5 所示. 图10-5 Writer的类层次结构图 表 10-3 列出了 Writer 的主要子类及说明. 表 10-3 Writ ...