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

2024-06-21 01:52
文章标签 检测 编程 网络 超时

本文主要是介绍网络编程(七)网络超时检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、概念
  • 二、实现方式
    • (一) 使用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. 端口复用


4. 设置超时时间


(三) alarm

1. 相关概念

2. sigaction

这篇关于网络编程(七)网络超时检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1079877

相关文章

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Python设置Cookie永不超时的详细指南

《Python设置Cookie永不超时的详细指南》Cookie是一种存储在用户浏览器中的小型数据片段,用于记录用户的登录状态、偏好设置等信息,下面小编就来和大家详细讲讲Python如何设置Cookie... 目录一、Cookie的作用与重要性二、Cookie过期的原因三、实现Cookie永不超时的方法(一)

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Linux网络配置之网桥和虚拟网络的配置指南

《Linux网络配置之网桥和虚拟网络的配置指南》这篇文章主要为大家详细介绍了Linux中配置网桥和虚拟网络的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、网桥的配置在linux系统中配置一个新的网桥主要涉及以下几个步骤:1.为yum仓库做准备,安装组件epel-re

python如何下载网络文件到本地指定文件夹

《python如何下载网络文件到本地指定文件夹》这篇文章主要为大家详细介绍了python如何实现下载网络文件到本地指定文件夹,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...  在python中下载文件到本地指定文件夹可以通过以下步骤实现,使用requests库处理HTTP请求,并结合o

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async