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,网络数 ...
随机推荐
- 怎样初始化XMLHttpRequest实例对象xhr
xhr.open() 接收5个参数, 用于初始化一个http请求, 它接收5个参数: 1. method: 请求类型; 2. url: 请求的url; 3. async: 是否为异步, 默认为true ...
- Kirinriki 2017多校
由于每个串的长度为5000,我们去枚举两个自串的对称点(这里注意一下,枚举的时候有两种情况的区间),然后用尺取法爬一遍. ac代码: #include<iostream> #include ...
- SpringBoot 异步调用方法并接收返回值
项目中肯定会遇到异步调用其他方法的场景,比如有个计算过程,需要计算很多个指标的值,但是每个指标计算的效率快慢不同,如果采用同步执行的方式,运行这一个过程的时间是计算所有指标的时间之和.比如: 方法A: ...
- 我是如何将一个加载90s的接口优化到不足2s的
一.提出问题 由于公司是做医疗级智能可穿戴设备的,所以数据(二进制数据)的存储方面有点特殊,数据没有存储于数据库里面,而是存储于磁盘上.可能有同学质疑,mysql的Blob类型也可以存储二进制数据啊, ...
- Oracle---PL/SQL的学习
PL/SQL程序 一.定义 declare 说明部分 begin 语句序列(DML语句) exception 例外处理语句 end; 二. 变量和常量说明 a) 说明变量(char,varchar2, ...
- Java后端开发常用工具
Java后端开发常用工具推荐: 俗话说,工欲善其事,必先利其器.不过初学时候不大建议过度依赖IDE等过多工具,这会让自己的编程基础功变得很差,比如各种语法的不熟悉,各种关键字比如synchronize ...
- BRD——>MRD——>PRD,产品经理三大文档概念详解及前后逻辑
转自:https://blog.csdn.net/neikutaixiao/article/details/40819445 商业需求文档Business Requirement DocumentBR ...
- C#面向对象 (访问修饰符、封装、继承、多态)
先看一下创建一个新项目时的基本格式 using System; using System.Collections.Generic; using System.Linq; //引用的命名空间 using ...
- VUE【二、选项和生命周期】
vue对象,类似于一个viewModel,是处理页面显示的数据模型的对象 其中会有很多选项,以下为较常用的: 选项 1.data-数据 vue实例会代理其data对象里的所有属性 2.methods- ...
- django-bootstrap4|django 加载popper.min.js失败
1.现象 2.解决过程 2.1.右键查看网页源代码 在浏览器地址栏打开popper.min.js对应的URL,发现无法打开,这个地址是国外的,需要找一个可访问的地址替换. 2.2.找到URL在djan ...