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和异步( ...
随机推荐
- OpenCV 2.4.9 学习笔记(1)—— 基本功能结构
一些关于OpenCV(2.4.9版本)的学习笔记,作为记录,以免自己忘了. 安装与配置 OpenCV的下载.安装以及在各个平台(Windows/Linux等)配置网上有很多的资料,自己就不用存了.需要 ...
- Aspose.Cells 基础用法
最近使用Aspose.Cells做Excel,在怎么添加批注和添加内部导航链接上耗费了一些时间,最后在官网上找到相关用法,记录一下. 代码不用过多介绍,看看即可明白. 测试代码下载 Workbook ...
- [poj_3469]多核CPU
Sample Input 3 1 1 10 2 10 10 3 2 3 1000 Sample Output 13 最小割,把模块看做点,建源点s和汇点t,以下(a,b,c)表示从a向b连一条容量为c ...
- Appium+python自动化15-在Mac上环境搭建【转载】
前言 mac上搭建appium+python的环境还是有点复杂的,需要准备的软件 1.nodejs 2.npm 3.cnpm 4.appium 5.pip 6.Appium-Python-Client ...
- 使用dom4j工具包对xml文件解析
xml文件 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http: ...
- BootStrap容器介绍
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
- C# api基础1
1.创建一个简单的api 目录结构 再创建一个controller用来测试 public class DefaultController : ApiController { public string ...
- Python_Tips[3] -> sort/sorted 排序函数
排序函数 / Sort Function list自带的sort函数可以实现对列表的排列功能,具有同样功能的还有sorted函数. 基本形式 列表有自己的sort方法,其对列表进行原址排序,既然是原址 ...
- 探究堆喷射(heap spray)
博客园的自动保存系统真心不咋地,写的差不多的文章蓝屏之后就没有了,醉了! 浏览器是互联网世界最主要的软件之一,从IE6到IE11安全攻防在不断升级,防御措施的实施促使堆喷射技巧不断变化.写这篇博文想好 ...
- mysql语法语句
将一个字段中的timestamp修改成可视化时间 update table set f1 = IF( LOCATE('-',f1)>0, f1, IFNULL(FROM_UNIXTIME(f1/ ...