Linux网络编程五、套接字超时
1.accept超时
accept等待并接受连接请求的过程是阻塞的,可以通过IO转接来设置等待一定的时长,如果超时没有连接,就让这个函数返回,让当前进程/线程处理别的任务。
例:
// 最大的文件描述符是: lfd
fd_set rdset;
FD_ZERO(&rdset);
FD_SET(lfd, &rdset);
struct timeval tm = {, }; //设置超时时长10s
int ret = select(lfd+, &rdset, NULL, NULL, &tm);
if(ret == )
{
// 超时, 不等了
return;
}
//有连接请求
else if(ret > )
{
accept(lfd, addr, len); // 必然不阻塞
}
2.read、write超时
同accept。
/*read*/
// 最大的文件描述符是: 通信的 connfd
fd_set rdset;
FD_ZERO(&rdset);
FD_SET(connfd, &rdset);
struct timeval tm = {, };
int ret = select(connfd+, &rdset, NULL, NULL, &tm);
if(ret == )
{
// 超时, 不等了
}
//有数据可读
else if(ret > )
{
read(connfd, buf, size); // 必然不阻塞
} /*write*/
//写缓冲区被写满,在写会造成阻塞
//对方不接收数据,本地写缓冲区一直阻塞。
fd_set wrset;
FD_ZERO(&wrset);
FD_SET(connfd, &wrset);
struct timeval tm = {, };
int ret = select(connfd+, NULL, &wrset, NULL, &tm);
if(ret == )
{
// 超时, 不等了, 写缓冲区还是满的
}
else if(ret > )
{
// 写缓冲区可写
write(connfd, buf, size);
}
3.connect超时
connect内部有一个超时检测,connect是一个阻塞函数,会阻塞等待服务器返回连接的结果。
如果要完成自己的connect超时检测,首先要将connect变成非阻塞。然后根据connect函数返回判断。
Posix定义了与select/epoll和非阻塞connect相关的规定:
connect连接建立成功,Socket描述符变为可写。
connect连接建立失败,Socket描述符既可读又可写。(由于有未决的错误,从而可读又可写)
连接失败,错误判定方式:
使用select检测,socket可读可写,只能在可读集合通过getsockopt获取错误代码。
使用epoll检测,socket可读可写,只能在EPOLLERR中通过getsockopt获取错误码。
// 1. 设置connect的非阻塞, 修改fd的属性
int fl = fcntl(fd, F_GETFL);
fl |= O_NONBLOCK;
fcntl(fd, F_SETFL, fl);
// 2. 连接服务器
int ret = conect(connfd, serveraddr, len);
// 返回-1: 连接失败, errno==EINPROGRESS,说明在连接过程中
if(ret == - && errno == EINPROGRESS)
{
fd_set wrset;
FD_ZERO(&wrset);
FD_SET(connfd, &wrset);
struct timeval tm = {, };
int ret = select(connfd+, NULL, &wrset, NULL, &tm);
if(ret == )
{
// 超时, 连接还没有完成
}
else if(ret > ) // ==1
{
// 判断连接是成功还是失败
int op;
int len = sizeof(op);
getsockopt(connfd, SOL_SOCKET, SO_ERROR, &op, &len);
if(op == )
{
// 正常
}
else if(op == -)
{
// 错误
}
}
}
//4.设置回阻塞模式
fcntl(fd, F_SETFL, fl&(~O_NONBLOCK);
windows下设置阻塞模式
unsigned long ul = 1;
ioctlsocket(this->m_connfd, FIONBIO, &ul);
非阻塞
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
// 判断错误
sockfd: 文件描述符
level: SOL_SOCKET
optname: SO_ERROR
optval: int 类型, 存储错误状态
optlen: optval大小对一个的以地址
Linux网络编程五、套接字超时的更多相关文章
- Linux网络编程——原始套接字实例:MAC 头部报文分析
通过<Linux网络编程——原始套接字编程>得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢? 链路层封包格式 M ...
- Linux网络编程之套接字基础
1.套接字的基本结构 struct sockaddr 这个结构用来存储套接字地址. 数据定义: struct sockaddr { unsigned short sa_family; /* addre ...
- Linux网络编程——原始套接字编程
原始套接字编程和之前的 UDP 编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据.区别在于,原始套接字可以自行组装数据包(伪装本地 IP,本地 MAC),可以接收本机网卡上所有 ...
- Linux网络编程——原始套接字能干什么?
通常情况下程序员接所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的 Socket,针对于面向连接的TCP 服务应用: (2)数据报式套接字(SOCK ...
- LINUX 网络编程 原始套接字
一 原始套接字 原始套接字(SOCK_RAW)是一种不同于SOCK_STREAM.SOCK_DGRAM的套接字,它实现于系统核心.然而,原始套接字能做什么呢?首先来说,普通的套接字无法处理ICMP.I ...
- UNIX网络编程——设置套接字超时
在涉及套接字的I/O操作上设置超时的方法有以下3种: 调用alarm,它在指定超时期时产生SIGALRM信号.这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm ...
- Linux 网络编程 高级套接字
一.套接字选项: 有以下3中方式可以对套接字选项进行设置: getsockopt 和 setsockopt 函数 fcntl函数 ioctl函数 getsockopt和setsockopt函数用于获得 ...
- Linux网络编程(五)
/*Linux网络编程(五)——多路IO复用之select() 网络编程中,使用IO复用的典型场合: 1.当客户处理多个描述字时(交互式输入以及网络接口),必须使用IO复用. 2.一个客户同时处理多个 ...
- TCP/IP网络编程之网络编程和套接字
网络编程和套接字 网络编程又称为套接字编程,就是编写一段程序,使得两台连网的计算机彼此之间可以交换数据.那么,这两台计算机用什么传输数据呢?首先,需要物理连接,将一台台独立的计算机通过物理线路连接在一 ...
- 【TCP/IP网络编程】:01理解网络编程和套接字
1.网络编程和套接字 网络编程与C语言中的printf函数和scanf函数以及文件的输入输出类似,本质上也是一种基于I/O的编程方法.之所以这么说,是因为网络编程大多是基于套接字(socket,网络数 ...
随机推荐
- antd做form表单的组件共用,利用mapPropsToFields填写默认值
做单页应用,不管是用Vue还是React,或者其他,有一个重要的原则,就是:组件重用. 既然组件可以重用,那么当添加一个信息,和修改该信息的布局必然是一致的,这时候,最好的方法自然是利用同一个组件,在 ...
- TCP协议探究(一):报文格式与连接建立终止
一 TCP:传输控制协议报文格式 1 TCP服务 提供面向连接.可靠的字节流服务 面向连接意味着两方通信,不支持多播和广播 可靠性的支持: 应用数据被分割成TCP认为最适合发送的数据块.由TCP传递给 ...
- TCP面向字节流和UDP面向报文的区别
TCP面向字节流 打个比方比喻TCP,你家里有个蓄水池,你可以里面倒水,蓄水池上有个龙头,你可以通过龙头将水池里的水放出来,然后用各种各样的容器装(杯子.矿泉水瓶.锅碗瓢盆)接水. 上面的例子中,往水 ...
- Spark机器学习API之特征处理(一)
Spark机器学习库中包含了两种实现方式,一种是spark.mllib,这种是基础的API,基于RDDs之上构建,另一种是spark.ml,这种是higher-level API,基于DataFram ...
- JavaScript02
一. 判断// 三元表达式// 循环// 判断: 用的最多的就是if判断// 1.// if(条件){// 当条件满足以后执行的语句// } // 2.// if(条件){// // }else{// ...
- STM32启动BOOT0 BOOT1设置方法
原理图 启动方式 第一种启动方式是最常用的用户FLASH启动.默认启动方式 第二种启动方式是STM32内嵌的SRAM启动.该模式用于调试 第三种启动方式是系统存储器启动方式,不建议使用这种,速度比较慢 ...
- 安卓开发之Toolbar返回键
本文前三步演示了为Toolbar添加返回键并实现返回的步骤,第四步给出了设置返回键颜色的方法. 1.在xml布局中引用toolbar: <android.support.design.widge ...
- [LeetCode] 40. Combination Sum II ☆☆☆(数组相加等于指定的数)
https://leetcode.wang/leetCode-40-Combination-Sum-II.html 描述 Given a collection of candidate numbers ...
- (二十三)ARM平台NEON指令的编译和优化
ARM平台NEON指令的编译和优化 本文介绍了ARM平台基于ARM v7-A架构的ARM Cortex-A系列处理器(Cortex-A5, Cortex-A7,Cortex-A8, Cortex-A9 ...
- windows10 L2tP nat 下无法连接的处理
事件查看器中没有错误代码显示. Windows 10 L2TP/IPsec Manual Setup Instructions Bold items are things you will click ...