1.套接字I/O超时设置方法

1.alarm

void handler(int sig) {

return 0;

}

signal(SIGALRM, handler);

alarm(5);

int ret = read(fd, buf, sizeof(buf));

if(ret == -1 &&errno == EINTR) {

errno = ETIMEDOUT;

} else if(ret >=0) {

alarm(0);

}

2.套接字选项

SO_SNDTIMEO

SO_RCVTIMEO

setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, 5);

int ret = read(fd, buf, sizeof(buf));

if(ret == -1 &&errno == EWOULDBLOCK) {

errno = ETIMEDOUT;

} else if(ret >=0) {

alarm(0);

}

3.select

2.用select实现超时

1.read_timeout函数封装

/*** read timeout - 读超时检测函数,不含读操作* @fd:文件描述符* @wait_seconds:等待超时秒数,如果为0不检测超时* 成功(未超时) 返回0,失败返回-1,超时返回-1并且errno = ETIMEDOUT*/
int read_timeout(int fd, unsigned int wait_seconds)
{int ret = 0;if (wait_seconds > 0){fd_set read_fdset;struct timeval timeout;FD_ZERO(&read_fdset);FD_SET(fd, &read_fdset);timeout.tv_sec = wait_seconds;timeout.tv_usec = 0;do{ret = select(fd + 1, &read_fdset, NULL, NULL, &timeout);} while (ret < 0 && errno == EINTR);if (ret == 0){ret = -1;errno = ETIMEDOUT;}else if (ret == 1)ret = 0;}return ret;
}

2.write_timeout函数封装

/*** write timeout - 写超时检测函数,不含写函数* @fd:文件描述符* @wait_seconds:等待超时秒数,如果为0不检测超时* 成功(未超时) 返回0,失败返回-1,超时返回-1并且errno = ETIMEDOUT*/
int write_timeout(int fd, unsigned int wait_seconds)
{int ret = 0;if (wait_seconds > 0){fd_set write_fdset;struct timeval timeout;FD_ZERO(&write_fdset);FD_SET(fd, &write_fdset);timeout.tv_sec = wait_seconds;timeout.tv_usec = 0;do{ret = select(fd + 1, NULL, NULL, &write_fdset, &timeout);} while (ret < 0 && errno == EINTR);if (ret == 0){ret = -1;errno = ETIMEDOUT;}else if (ret == 1)ret = 0;}return ret;
}

3.accept_timeout函数封装

/*** accept_timeout - 带超时的accept* @fd:套接字* @addr:输出参数,返回对方地址* @wait_seconds:等待超时秒数,如果为0表示正常模式* 成功(未超时)返回已连接套接字,超时返回-1并且errno = ETIMEDOUT*/
int accept_timeout(int fd, struct sockaddr_in *addr, unsigned int wait_seconds)
{int ret;socklen_t addrlen = sizeof(struct sockaddr_in);if (wait_seconds > 0){fd_set accept_fdset;struct timeval timeout;FD_ZERO(&accept_fdset);FD_SET(fd, &accept_fdset);timeout.tv_sec = wait_seconds;timeout.tv_usec = 0;do{ret = select(fd + 1, &accept_fdset, NULL, NULL, &timeout);} while (ret < 0 && errno == EINTR);if (ret == -1)return -1;else if (ret == 0){errno = ETIMEDOUT;return -1;}}if (addr != NULL)ret = accept(fd, (struct sockaddr*)addr, &addrlen);elseret = accept(fd, NULL, NULL);
/*  if (ret == -1)ERR_EXIT("accept");*/return ret;
}

4.connect_timeout函数封装

/*** active_nonblock - 设置I/O为非阻塞模式* @fd:文件描述符*/
void active_nonblock(int fd) {int ret;int flags = fcntl(fd, F_GETFL);if(-1 == flags) ERR_EXIT("fcntl");flags |= O_NONBLOCK;ret = fcntl(fd, F_SETFL, flags);if(-1 == ret)ERR_EXIT("fcntl");
}/*** deactive_nonblock - 设置I/O为阻塞模式* @fd:文件描述符*/
void deactive_nonblock(int fd) {int ret;int flags = fcntl(fd, F_GETFL);if(-1 == flags) ERR_EXIT("fcntl");flags &= ~O_NONBLOCK;ret = fcntl(fd, F_SETFL, flags);if(ret == -1) ERR_EXIT("fcntl");
}/*** connect timeout - connect* @fd:套接字* @addr:要连接的地址* @wait_seconds:等待超时秒数,如果为0表示正常模式* 成功(未超时)返回0,失败返回-1,超时返回-1并且errno = ETIMEDOUT*/
int connect_timeout(int fd, struct sockaddr_in *addr, unsigned int wait_seconds)
{int ret;socklen_t addrlen = sizeof(struct sockaddr_in);if (wait_seconds > 0)activate_nonblock(fd);ret = connect(fd, (struct sockaddr*)addr, addrlen);if (ret < 0 && errno == EINPROGRESS){//printf("AAAAA\n");fd_set connect_fdset;struct timeval timeout;FD_ZERO(&connect_fdset);FD_SET(fd, &connect_fdset);timeout.tv_sec = wait_seconds;timeout.tv_usec = 0;do{/*一旦连接建立,套接字就可写*/ret = select(fd + 1, NULL, &connect_fdset, NULL, &timeout);} while (ret < 0 && errno == EINTR);if (ret == 0){ret = -1;errno = ETIMEDOUT;}else if (ret < 0)return -1;else if (ret == 1){//printf("BBBBB\n");/*ret返回为1,可能有两种情况,一种是连接建立成功,一种是套接字产生错误*//*此事错误信息不会保存至errno变量中,因此,需要调用getsockopt来获取*/int err;socklen_t socklen = sizeof(err);int sockoptret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &socklen);if (sockoptret == -1){return -1;}if (err == 0){//printf("DDDDDDD\n");ret = 0;}else{//printf("CCCCCC\n");errno = err;ret = -1;}}}if (wait_seconds > 0){deactivate_nonblock(fd);}return ret;
}
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>#define ERR_EXIT(m) \do \{ \perror(m); \exit(EXIT_FAILURE); \}while(0)

socket编程(十一)相关推荐

  1. python基础之socket编程

    阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 八 基于UDP的套接字 九 粘包现象 ...

  2. python网络编程-socket编程

    一.服务端和客户端 BS架构 (腾讯通软件:server+client) CS架构 (web网站) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 二.OSI七层模 ...

  3. 查看队列深度_不为人知的网络编程(十一):从底层入手,深度分析TCP连接耗时的秘密...

    " 本文作者张彦飞,原题"聊聊TCP连接耗时的那些事儿",本次收录已征得作者同意,转载请联系作者.即时通讯网收录时有少许改动.本文已同步发布于52im社区:http:// ...

  4. Windows Socket编程笔记之最简单的小Demo

    Windows Socket编程的大致过程: 服务器端: ----过程-------------对应的API-------  0.初始化         |  WSAStartup()  1.创建So ...

  5. Linux下Socket编程

    Linux下Socket编程    网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的S ...

  6. [Python_7] Python Socket 编程

    0. 说明 Python Socket 编程 1. TCP 协议 [TCP Server] 通过 netstat -ano 查看端口是否开启 # -*-coding:utf-8-*-"&qu ...

  7. C# Socket编程(5)使用TCP Socket

    TCP 协议(Transmission Control Protocol,传输控制协议)是TCP/IP体系中面向连接(connection oriented)的传输层(transport layer) ...

  8. 【.Net MF网络开发板研究-04】Socket编程之服务端

    前几篇文章介绍了Http相关的应用,其实从技术角度而言,应该先介绍Socket编程,然后再介绍Http,毕竟Http是用Socket相关函数编程实现的. .NET Micro Framework的So ...

  9. socket编程缓冲区大小对send()的影响

    1. 概述 Socket编程中,使用send()传送数据时,返回结果受到以下几个因素的影响: • Blocking模式或non-blocking模式 • 发送缓冲区的大小 • 接收窗口大小 本文档介绍 ...

  10. 华中科技大学计算机通信与网络实验,华中科技大学计算机通信与网络实验报告Socket编程实验.docx...

    实验一 Socket编程实验 1.1环境 开发环境:Windows 10 64 位,Intel Core i5-7300HQ CPU, 8GB 内存 1.1. 1开发平台 Microsoft Visu ...

最新文章

  1. 算法入门书籍--算法图解
  2. 电脑键盘下划线怎么打_电脑键盘右边的数字键无法使用怎么办?
  3. Wiwiz无线Web认证实现限速
  4. hb编程软件全称_什么是组态软件、组态编程?
  5. python scapy模块安装_python scapy模块安装与依赖模块
  6. 高效代码审查的十个经验
  7. UPUPW数据库密码的修改
  8. rsyslog-mysql_04-Log rsyslog-mysql loganalyzer
  9. ASP.NET 数据绑定常用代码及其性能分析
  10. 打造Vim作为前端IDE
  11. openresty连接mysql_在CentOS 6上使用openresty访问mysql
  12. 提供一个文档下载接口,用httpclient下载文件
  13. 本科蓝色学术论文答辩PPT模板
  14. doc文件转换为docx文件
  15. 搜狗双拼如何打单韵母字
  16. 什么是PT,PT和BT有什么不同?
  17. deep learning实践经验总结
  18. 5e服务器显示fps被锁定,csgo强制被锁60帧 被锁60fps解决方法
  19. 活动如何造势推广?会议软件帮您忙
  20. vscode html注释快捷键_最强编辑器 VSCode 系列之插件推荐【不定期更新】

热门文章

  1. Google发布Puppeteer 1.0
  2. 静态tableview组背景色的更改及自定义cell的两种方式
  3. jquery1.8.3和1.11.3的用法区别
  4. PHP移动互联网开发(1)——环境搭建及配置
  5. codeforces#253 D - Andrey and Problem里的数学知识
  6. Golang错误和异常处理的正确姿势
  7. 【软件工程实践 · 团队项目】 第一次作业
  8. HDU 1114 iggy-Bank(完全背包)
  9. android studio 1.2.1.1导入library project(以sharesdk为例)
  10. 在线CSV转JSON工具