//read操作加上超时时间。
1 int read_timeout(int fd, void *buf, uint32_t count, int time)
{
if(time > ) {
fd_set rSet;
FD_ZERO(&rSet);
FD_SET(fd, &rSet); struct timeval timeout;
memset(&timeout, , sizeof(timeout));
timeout.tv_sec = time;
timeout.tv_usec = ; int ret;
while() {
ret = select(fd+, &rSet, NULL, NULL, &timeout);
if(ret < ) {
if(errno == EINTR) continue;
ERR_EXIT("select");
} else if(ret == ) {
errno = ETIMEDOUT;
return -;
} else {
break;
}
}
}
int readNum;
readNum = read(fd, buf, count);
return readNum;
}

写超时

 int write_timeout(int fd, void *buf, uint32_t count, int time)
{
if(time > ) {
fd_set wSet;
FD_ZERO(&wSet);
FD_SET(fd, &wSet); struct timeval timeout;
memset(&timeout, , sizeof(timeout));
timeout.tv_sec = time;
timeout.tv_usec = ; int ret;
while() {
ret = select(fd+, NULL, &wSet, NULL, &timeout);
if(ret < ) {
if(errno == EINTR) continue;
ERR_EXIT("select");
} else if(ret == ) {
errno = ETIMEDOUT;
return -;
} else {
break;
}
}
}
int writeNum;
writeNum = write(fd, buf, count);
return writeNum;
}

accept超时操作

int accept_timeout(int fd, struct sockaddrin *addr, socklen_t *addrlen, int time)
{
int ret;
if(time > ) {
fd_set rSet;
FD_ZERO(&rSet);
FD_SET(fd, &rSet); struct timeval timeout;
timeout.tv_sec = time;
timeout.tv_usec = ; int selectRet;
do {
selectRet = select(fd + , &rSet, NULL, NULL, &timeout);
}while(selectRet < && selectRet == EINTR);
if(selectRet < ) {
return -;
} else if(selectRet == ) {
errno = ETIMEDOUT;
return -;
}
}
if(addr) {
ret = accept(fd, (struct sockaddr *)addr, addrlen);
} else {
ret = accept(fd, NULL, NULL);
}
return ret;
}

检测监听套接字是否可读,当监听套接字可读的时候,就认为连接队列发生了连接。

connect

 void setNonBlockMode(int fd)
{
int flags = fcntl(fd, F_GETFL);
if(flags < ) {
ERR_EXIT("fcntl");
}
flags |= O_NONBLOCK;
if(fcntl(fd, F_SETFL, flags) < ) {
ERR_EXIT("fcntl");
}
} void setBlockMode(int fd)
{
int flags = fcntl(fd, F_GETFL);
if(flags < ) {
ERR_EXIT("fcntl");
}
flags &= ~O_NONBLOCK;
if(fcntl(fd, F_SETFL, flags) < ) {
ERR_EXIT("fcntl");
} } int connect_timeout(int sockfd, struct sockaddrin *addr, socklen_t addrlen, int time)
{
int ret = -; if(time > ) {
setNonBlockMode(sockfd);
}
ret = connect(sockfd, (struct sockaddr*)addr, addrlen);
if(ret < && errno == EINPROGRESS) {
fd_set wSet;
FD_ZERO(&wSet);
FD_SET(sockfd, &wSet); struct timeval timeout;
timeout.tv_sec = time;
timeout.tv_usec = ; int selcetRet;
do{
selcetRet = select(sockfd + , NULL, &wSet, NULL, &timeout);
}while(selcetRet < && errno == EINTR);
if(selcetRet < ) {
ret = -;
} else if(selcetRet == ) {
ret = -;
errno = ETIMEDOUT;
} else if(selcetRet > ) {
int err;
socklen_t socklen = sizeof(err);
int sockoptRet = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &socklen);
if(sockoptRet == -) {
ret = -;
}
if(err == ) {
ret = ;
} else {
errno = err;
ret = -;
}
}
}
if(time > ) {
setBlockMode(sockfd);
}
return ret;
}

1.设置fd为非阻塞模式。

2.调用connect操作,如果网络条件很好,比如本机两个socket发生连接,会发生成功返回。

3.正常情况下,connect立即返回-1并设置errno为EINPROGRESS 表示正在连接过程中。

4.使用select检测fd是否可写。 如果检测到可写也有如下两种情况:

  1. connect连接成功。

  2. 产生了错误,我们就需要用getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &socklen); 来判断是否发生了错误。

read,write,accept,connect 超时封装的更多相关文章

  1. C Socket编程之Connect超时 (转)

    网络编程中socket的分量我想大家都很清楚了,socket也就是套接口,在套接口编程中,提到超时的概念,我们一下子就能想到3个:发送超时,接收超时,以及select超时(注:select函数并不是只 ...

  2. VC socket Connect 超时时间设置

    设置connect超时很简单,CSDN上也有人提到过使用select,但却没有一个令人满意与完整的答案.偶所讲的也正是select函数,此函数集成在winsock1.1中,简单点讲,"作用使 ...

  3. 设置linux中tcp默认的20秒connect超时时间(转)

    无论你用任何语言或者是网络库,你都可以设置网络操作的超时时间,特别是connect.read.write的超时时间. 你可以在代码中把超时时间设置任意大小值,但是connect方法会有一点特殊. co ...

  4. linux下connect超时时间探究

    最近在linux做服务器开发的时候,发现了一个现象:服务器在启动的时候调用了 connect 函数,因为连接了一个不可用的端口,导致connect最后报出了 “Connection timed out ...

  5. linux 设置connect 超时代码[select/epoll]

    转载请注明来源:https://www.cnblogs.com/hookjc/ linux下socket编程有常见的几个系统调用: 对于服务器来说, 有socket(), bind(),listen( ...

  6. [转]windows下设置socket的connect超时

    原文地址:http://www.cnblogs.com/BloodAndBone/archive/2012/05/22/2513338.html 变相的实现connect的超时,我要讲的就是这个方法, ...

  7. iOS 设置connect超时

    NSLock *theLock; [theLock lock]; int fd, error; struct sockaddr_in addr; ))<) { cout<<" ...

  8. Linux下connect超时处理【总结】

    1.前言 最近在写一个测试工具,要求快速的高效率的扫描出各个服务器开放了哪些端口.当时想了一下,ping只能检测ip,判断服务器的网络是连通的,而不能判断是否开放了端口.我们知道端口属于网络的应用层, ...

  9. Socket相关函数(1)- socket(), bind(), listen(), accept(), connect(), TCP模型

    tcp_server.c #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #in ...

随机推荐

  1. 使用fuser命令kill一个终端(特殊文件)的方法

    /*********************************************************************  * Author  : Samson  * Date   ...

  2. Foundation框架 - NSException类

    NSException类 WBStudentManager.h #import <Foundation/Foundation.h> NSString* const NameInvalidE ...

  3. 实现iOS7上tableView的切割线像iOS6中的效果

    iOS7上tableView的切割线左边短了一点,要实现和iOS6中的效果还是有方法的,UITableView头文件中个属性: @property (nonatomic)         UIEdge ...

  4. 将UIBezierPath存为自己定义格式的字符串,再将字符串转为UIBezierPath

    <pre name="code" class="objc">自己定义字符串格式为:@"123.02,234.23|321.23,432.0 ...

  5. Model Vaildation

    https://docs.asp.net/en/latest/mvc/models/validation.html 许多有用的验证属性都必须引用命名空间: System.ComponentModel. ...

  6. C#实现网段扫描

    目录1.使用的类2.获取本地主机IP地址3.远程查询4.实现网段的扫描 ---------------------------------------------------------------- ...

  7. wordpress系列1:安装

    https://wordpress.org/download/release-archive/ 官方中文网站:https://cn.wordpress.org/ readme.html文件,可查看Wo ...

  8. spring boot Mybatis多数据源配置

    关于 有时候,随着业务的发展,项目关联的数据来源会变得越来越复杂,使用的数据库会比较分散,这个时候就会采用多数据源的方式来获取数据.另外,多数据源也有其他好处,例如分布式数据库的读写分离,集成多种数据 ...

  9. Linux 操作系统中的进程结构

    前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ...

  10. Android Material Design 中文版

    http://www.google.com/design/spec/animation/authentic-motion.html http://www.oschina.net/question/14 ...