网络编程(七)网络超时检测

文章目录

  • 一、概念
  • 二、实现方式
    • (一) 使用select实现超时检测
      • 1. select函数补充说明:
      • 2. 使用示例
      • 3. 输出结果
    • (二) 使用setsockopt函数
      • 1. 函数定义
      • 2. 获取发送缓冲区和接收缓冲区的大小
      • 3. 端口复用
      • 4. 设置超时时间
    • (三) alarm
      • 1. 相关概念
      • 2. sigaction

一、概念

介于阻塞和非阻塞之间,可以自己设置一个时间,在设置的时间内,如果没数据就阻塞等待,如果设置的时间到了还没数据,则立即切换为非阻塞。

二、实现方式

(一) 使用select实现超时检测

1. select函数补充说明:

#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);其中 最后一个参数 timeout 就是超时时间NULL 永久阻塞 直到就绪为止也可以使用下面的结构体指定超时时间struct timeval {long    tv_sec;         /* 秒 */long    tv_usec;        /* 微秒 */};如果结构体的两个成员都为 0  则表示非阻塞返回值:成功 就绪的文件描述符个数失败 -1 重置错误码超时  0
  • 注:
  • select采用倒计时方式计时,如果在循环中使用,需要每次重置时间
  • 超时时,select会返回0

2. 使用示例

#include <my_head.h>int main(int argc, char const *argv[])
{if(3 != argc){printf("Usage:%s Ipv4 port\n",argv[0]);exit(-1);}//创建套接字int sockfd=0;if(-1 ==(sockfd = socket(AF_INET,SOCK_STREAM,0))){ERR_LOG("socket error");}//填充结构体struct sockaddr_in serveraddr;serveraddr.sin_family=AF_INET;serveraddr.sin_addr.s_addr=inet_addr(argv[1]);serveraddr.sin_port=htons(atoi(argv[2]));socklen_t serverlen = sizeof(serveraddr);//绑定if(-1 == bind(sockfd,(struct sockaddr *)&serveraddr,serverlen)){ERR_LOG("bind error");}//开启监听if(-1 ==listen(sockfd,5)){ERR_LOG("listen error");}//创建集合fd_set readfds;FD_ZERO(&readfds);fd_set tempfds;FD_ZERO(&tempfds);int acceptfd=0;int max_fd=0;int ret=0;int i=0;int nbytes=0;char buff[128]={0};//将套接字加入集合FD_SET(sockfd,&readfds);max_fd=max_fd>sockfd?max_fd:sockfd;struct timeval tm;while(1){tm.tv_sec=5;tm.tv_usec=0;tempfds = readfds;if(-1 == (ret = select(max_fd+1,&tempfds,NULL,NULL,&tm))){ERR_LOG("select error");}else if(0 == ret){printf("已经五秒没有fd就绪了\n");continue;}printf("有fd就绪\n");//说明有fd就绪了,判断是不是sockfdfor(i=3;i<max_fd+1 && 0<ret;i++){//先判断是不是这个fd就绪了if(FD_ISSET(i,&tempfds)){ret--;//判断就绪的fd是不是sockfdif(sockfd == i){//说明有新的客户端接入if(-1 == (acceptfd = accept(i,NULL,NULL))){ERR_LOG("accept error");}//将新的acceptfd加入集合FD_SET(acceptfd,&readfds);max_fd=max_fd>acceptfd?max_fd:acceptfd;printf("用户[%d]连接\n",i);}else{//说明是已连接的客户端要通信printf("接收到用户[%d]的消息\n",i);if(-1 == (nbytes = recv(i,buff,sizeof(buff),0))){ERR_LOG("recv error");}else if(0 == nbytes){printf("用户[%d]断开连接\n",i);//从集合中删除FD_CLR(i,&readfds);close(i);continue;}if(!strcmp(buff,"quit")){//用户退出printf("用户[%d]退出\n",i);//从集合中删除FD_CLR(i,&readfds);close(i);continue;}//正常数据处理printf("用户[%d]发送消息[%s]\n",i,buff);strcat(buff,"T^T");if(-1 == send(i,buff,sizeof(buff),0)){ERR_LOG("send error");}}}}} close(sockfd);return 0;
}

3. 输出结果

在这里插入图片描述

(二) 使用setsockopt函数

1. 函数定义

#include <sys/types.h>
#include <sys/socket.h>int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);功能:设置或者获取套接字属性
参数:sockfd:要操作的套接字level:选项的级别套接字API级别  SOL_SOCKETTCP级别       IPPROTO_TCPIP级别        IPPROTO_IPoptname:选项的名字套接字API级别SO_BROADCAST  允许发送广播SO_RCVBUF     接收缓冲区的大小SO_SNDBUF     发送缓冲区的大小SO_RCVTIMEO   接收超时时间参数是一个 struct timeval 结构体如果超时了 调用会返回-1 错误码 为 EAGAINSO_SNDTIMEO   发送超时时间SO_REUSEADDR  允许端口复用TCP级别TCP_NODELAY   关闭Nagle算法IP级别IP_ADD_MEMBERSHIP  设置加入多播组optval:选项的值,没有特殊说明时,一般是int型指针;1打开;0关闭optlen:optval的长度
返回值:成功 0失败  -1 重置错误码
  • 注:如果参数没有特殊说明,一般是int型

2. 获取发送缓冲区和接收缓冲区的大小

#include <my_head.h>int main(int argc, char const *argv[])
{int sockfd=0;if(-1 == (sockfd = socket(AF_INET,SOCK_STREAM,0))){ERR_LOG("socket error");}int snd_buff_size = 0;int snd_buff_size_len = sizeof(snd_buff_size);if(-1 == getsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&snd_buff_size,&snd_buff_size_len)){ERR_LOG("getsockopt error");}printf("Sendbuff:%dKB\n",snd_buff_size/1024);int recv_buff_size = 0;int recv_buff_size_len = sizeof(recv_buff_size);if(-1 == getsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&recv_buff_size,&recv_buff_size_len)){ERR_LOG("getsockopt error");}printf("Recvbuff:%dKB\n",recv_buff_size/1024);return 0;
}

输出结果:
在这里插入图片描述

  • 注:默认 发送缓冲区16k,接收缓冲区128k。

3. 端口复用

int flag = 1;
if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)))ERR_LOG("setsockopt error");
//把上述代码加在  创建套接字之后 和 bind 之前即可

4. 设置超时时间

struct timeval tm;
tm.tv_sec = 5;
tm.tv_usec = 0;
if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tm, sizeof(tm)))ERR_LOG("setsockopt error");

当超时时,会立刻返回一个错误(EAGAIN),可以检测错误码来决定如何处理。

注:由已经设置过超时时间的 sockfd 产生的 acceptfd 会继承超时属性,
如果想用一样的超时时间,就无需对 acceptfd 设置了;
如果不想用一样的时间,可以使用setsockopt函数对每个acceptfd单独设置

(三) alarm

1. 相关概念

2. sigaction

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/359297.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】文件处理(IO流)

文章目录 C IO流1. C语言IO2. CIO2.1 C标准IO流2.2 C文件IO流2.3 C IO 文件常用函数总结表2.4 C stringstream C IO流 回顾一下&#xff0c;C语言中IO输入输出的 1. C语言IO C语言中常用的输入输出函数有如下几种&#xff1a;前者是格式化标准输入输出&#xff0c;后者是格式化…

探秘分布式一致性(共识)算法 :Raft

1.前言 Raft 算法是 Multi-Paxos 算法的一种&#xff0c;是一种强一致性算法。核心就是通过日志复制的方式达到整个集群的副本一致。 Raft 算法的三个核心概念就是 Leader 的选举、日志复制、节点变更。本文也将从这三个方面进行探讨。之后再聊聊 Raft 算法的几个应用场景。 2.…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-27含并行连结的网络GoogLeNet

27含并行连结的网络GoogLeNet import torch from torch import nn from torch.nn import functional as F import liliPytorch as lp import matplotlib.pyplot as pltclass Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, …

免费内网穿透工具 ,快解析内网穿透解决方案

在IPv4公网IP严重不足的环境下&#xff0c;内网穿透技术越来越多的被人们所使用&#xff0c;使用内网穿透技术的好处有很多。 1&#xff1a;无需公网ip 物以稀为贵&#xff0c;由于可用的公网IP地址越来越少&#xff0c;价格也是水涨船高&#xff0c;一个固定公网IP一年的成本…

C++ 矩阵的最小路径和解法

描述 给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。 数据范围: 1≤𝑛,𝑚≤5001≤n,m≤500,矩阵中任意值都满足 0≤𝑎𝑖,𝑗≤1000≤ai,j​≤100 要求…

基于豆瓣电影TOP250的可视化设计

本文要完成的目的&#xff0c;实现豆瓣电影TOP250的可视化 思路 讲解思路&#xff0c;采用倒推的方式&#xff0c; 首先确定可视化图表&#xff0c;也就是最终的效果。这样就能确定需要那些基础数据根据需要的数据进行按需爬取存储。 本篇文章完成前两步。可视化图表设计 和 …

搜维尔科技:「案例」NBA新科冠军与Xsens运动捕捉的缘分

北京时间昨日&#xff0c;凯尔特人在主场106比88击败独行侠&#xff0c;以总比分4比1获胜&#xff0c;夺得队史第18冠&#xff0c;超越湖人队&#xff08;17冠&#xff09;成为历史上夺冠次数最多的球队。凯尔特人队上一次夺冠还是在2007-2008赛季。 凯尔特人队主力Jayson Tat…

采用C#+uni-app 公众号预约挂号系统源码 医院公众号1分钟搞定网上“挂缴查”攻略!

采用C#uni-app 公众号预约挂号系统源码 医院公众号1分钟搞定网上“挂缴查”攻略&#xff01; 医院就诊人数持续增多&#xff0c;为保障就诊人员安全便捷就医&#xff0c;减少排队等候时间&#xff0c;进一步提升就医体验&#xff0c;医院微信公众号上线缴费、查询等功能。就诊人…

Python+Pytest+Yaml+Request+Allure框架源代码之(一)common公共方法封装

common模块&#xff1a; get_path.py&#xff1a;获取路径方法 # -*- coding: UTF-8 -*- import os# 项目根目录 BASE_DIR os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 配置文件目录 CONFIG_DIR os.path.join(BASE_DIR,config)# 测试用例文件目录 TESTCA…

高速缓存存储器(Chche)

为了解决CPU和主存之间速度不匹配的问题&#xff0c;计算机系统中引入了高速缓存&#xff08;Chche&#xff09;的概念。 基本想法&#xff1a;使用速度更快但容量更小、价格更高的SRAM制作一个缓冲存储器&#xff0c;用来存放经常用到的信息&#xff1b;这样一来&#xff0c;…

如何打包数据库文件

使用 mysqldump 命令&#xff1a; mysqldump -u username -p database_name > output_file.sql username 是数据库的用户名。database_name 是要导出的数据库名称。output_file.sql 是导出的 SQL 文件名&#xff0c;可以自定义。 示例&#xff1a; mysqldump -u root -p…

Python-正则表达式

目录 一、打开正则表达式 二、正则表达式的使用 1、限定符 &#xff08;1&#xff09;x*&#xff1a;*表示它前面的字符y 可以有0个或多个&#xff1b; &#xff08;2&#xff09;x&#xff1a;表示它前面的字符可以出现一次以上&#xff1b;&#xff08;只可以匹配多次&…

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. 泛型编程 首先让我们来思考一个问题&#xff0c;如何实现一个交换函数&#x…

晨持绪科技:开好一家抖音小店运营怎么做

在数字时代&#xff0c;抖音小店以其独特的社交媒体优势迅速崛起&#xff0c;成为许多创业者的新宠。但如何有效运营&#xff0c;却是一门学问。首要任务是确定你的小店定位&#xff0c;这关系到后续的产品选择、目标客户群及营销策略。定位明确后&#xff0c;接下来便是挑选适…

工程文档CAD转换必备!在 Java 中将 DWG 转换为 JPG

Aspose.CAD 是一个独立的类库&#xff0c;以加强Java应用程序处理和渲染CAD图纸&#xff0c;而不需要AutoCAD或任何其他渲染工作流程。该CAD类库允许将DWG, DWT, DWF, DWFX, IFC, PLT, DGN, OBJ, STL, IGES, CFF2文件、布局和图层高质量地转换为PDF和光栅图像格式。 Aspose AP…

使用 GitHub Actions 编译和发布 Android APK

使用 GitHub Actions 编译和发布 Android APK 在现代软件开发中&#xff0c;持续集成和持续部署&#xff08;CI/CD&#xff09;已成为不可或缺的一部分。对于 Android 开发者来说&#xff0c;自动化编译和发布 APK 不仅节省时间&#xff0c;还能确保每次发布的一致性。本文将介…

电脑用什么录屏?这3款软件你值得拥有

随着电脑技术的发展&#xff0c;录屏已经成为用户日常办公、学习、娱乐的重要工具之一。录屏软件种类繁多&#xff0c;功能各异&#xff0c;但如何选择合适的录屏软件成为用户面临的难题。本文将介绍电脑用什么录屏&#xff0c;并推荐三款软件&#xff0c;通过对比分析各自的特…

24.6.16

星期一&#xff1a; 补cf global round26 C2 cf传送门 思路&#xff1a;有效操作2只有一次&#xff0c;且反转后不会再出现负数&#xff0c;即后面能贡献 2^n-i个方案&#xff0c;再乘上前面 2^(k>0的次数) 代码如下&…

Golang | Leetcode Golang题解之第166题分数到小数

题目&#xff1a; 题解&#xff1a; func fractionToDecimal(numerator, denominator int) string {if numerator%denominator 0 {return strconv.Itoa(numerator / denominator)}s : []byte{}if numerator < 0 ! (denominator < 0) {s append(s, -)}// 整数部分numer…

解决安全规模问题:MinIO 企业对象存储密钥管理服务器

在强大可靠的存储解决方案领域&#xff0c;MinIO 作为持久层脱颖而出&#xff0c;为组织提供安全、持久和可扩展的存储选项。MinIO 通常负责处理关键任务数据&#xff0c;在确保高可用性方面发挥着至关重要的作用&#xff0c;有时甚至在全球范围内。存储数据的性质&#xff0c;…