超时设置

//read操作加上超时时间。1 int read_timeout(int fd, void *buf, uint32_t count, int time)
 2 {
 3     if(time > 0) {
 4         fd_set rSet;
 5         FD_ZERO(&rSet);
 6         FD_SET(fd, &rSet);
 7 
 8         struct timeval timeout;
 9         memset(&timeout, 0, sizeof(timeout));
10         timeout.tv_sec = time;
11         timeout.tv_usec = 0;
12         
13         int ret;
14         while(1) {
15             ret = select(fd+1, &rSet, NULL, NULL, &timeout);
16             if(ret < 0) {
17                 if(errno == EINTR) continue;
18                 ERR_EXIT("select");
19             } else if(ret == 0) {
20                 errno = ETIMEDOUT;
21                 return -1;
22             } else {
23                 break;
24             }
25         }
26     }
27     int readNum;
28     readNum = read(fd, buf, count);
29     return readNum;
30 }

写超时

 1 int write_timeout(int fd, void *buf, uint32_t count, int time)
 2 {
 3     if(time > 0) {
 4         fd_set wSet;
 5         FD_ZERO(&wSet);
 6         FD_SET(fd, &wSet);
 7 
 8         struct timeval timeout;
 9         memset(&timeout, 0, sizeof(timeout));
10         timeout.tv_sec = time;
11         timeout.tv_usec = 0;
12         
13         int ret;
14         while(1) {
15             ret = select(fd+1, NULL, &wSet, NULL, &timeout);
16             if(ret < 0) {
17                 if(errno == EINTR) continue;
18                 ERR_EXIT("select");
19             } else if(ret == 0) {
20                 errno = ETIMEDOUT;
21                 return -1;
22             } else {
23                 break;
24             }
25         }
26     }
27     int writeNum;
28     writeNum = write(fd, buf, count);
29     return writeNum;
30 }

accept超时操作

int accept_timeout(int fd, struct sockaddrin *addr, socklen_t *addrlen, int time)
{
  int ret;
  if(time > 0) {
    fd_set rSet;
    FD_ZERO(&rSet);
    FD_SET(fd, &rSet);    struct timeval timeout;
    timeout.tv_sec = time;
    timeout.tv_usec = 0;    int selectRet;
    do {
      selectRet = select(fd + 1, &rSet, NULL, NULL, &timeout);
    }while(selectRet < 0 && selectRet == EINTR);
    if(selectRet < 0 ) {
      return -1;
    } else if(selectRet == 0) {
      errno = ETIMEDOUT;
      return -1;
    }	
  }
  if(addr) {
    ret = accept(fd, (struct sockaddr *)addr, addrlen);
  } else {
    ret = accept(fd, NULL, NULL);
  }
  return ret;
}

检测监听套接字是否可读,当监听套接字可读的时候,就认为连接队列发生了连接。

connect

 1 void setNonBlockMode(int fd)
 2 {
 3     int flags = fcntl(fd, F_GETFL);
 4     if(flags < 0) {
 5         ERR_EXIT("fcntl");
 6     }
 7     flags |= O_NONBLOCK;
 8     if(fcntl(fd, F_SETFL, flags) < 0) {
 9         ERR_EXIT("fcntl");
10     }
11 }
12 
13 void setBlockMode(int fd)
14 {
15     int flags = fcntl(fd, F_GETFL);
16     if(flags < 0) {
17         ERR_EXIT("fcntl");
18     }
19     flags &= ~O_NONBLOCK;
20     if(fcntl(fd, F_SETFL, flags) < 0) {
21         ERR_EXIT("fcntl");
22     }
23 
24 }
25 
26 int connect_timeout(int sockfd, struct sockaddrin *addr, socklen_t addrlen, int time)
27 {
28     int ret = -1;
29 
30     if(time > 0) {
31         setNonBlockMode(sockfd);
32     }    
33     ret = connect(sockfd, (struct sockaddr*)addr, addrlen);
34     if(ret < 0 && errno == EINPROGRESS) {
35         fd_set wSet;
36         FD_ZERO(&wSet);
37         FD_SET(sockfd, &wSet);
38         
39         struct timeval timeout;
40         timeout.tv_sec = time;
41         timeout.tv_usec = 0;
42         
43         int selcetRet;
44         do{
45             selcetRet = select(sockfd + 1, NULL, &wSet, NULL, &timeout);
46         }while(selcetRet < 0 && errno == EINTR);
47         if(selcetRet < 0) {
48             ret = -1;
49         } else if(selcetRet == 0) {
50             ret = -1;
51             errno = ETIMEDOUT;
52         } else if(selcetRet > 0) {
53             int err;
54             socklen_t socklen = sizeof(err);
55             int sockoptRet = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &socklen);
56             if(sockoptRet == -1) {
57                 ret = -1;
58             } 
59             if(err == 0) {
60                 ret = 0;
61             } else {
62                 errno = err;
63                 ret = -1;
64             }
65         }
66     }
67     if(time > 0) {
68         setBlockMode(sockfd);
69     }
70     return ret;
71 }

1.设置fd为非阻塞模式。

2.调用connect操作,如果网络条件很好,比如本机两个socket发生连接,会发生成功返回。

3.正常情况下,connect立即返回-1并设置errno为EINPROGRESS 表示正在连接过程中。

4.使用select检测fd是否可写。 如果检测到可写也有如下两种情况:

1. connect连接成功。

2. 产生了错误,我们就需要用getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, &socklen); 来判断是否发生了错误。

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

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

相关文章

字符串题目 1 --------判断两个字符串是否为旋转词

题目描述 如果一个字符串为str&#xff0c;把字符串的前面任意部分挪到后面形成的字符串交str的旋转词。比如str“12345”&#xff0c;str的旋转串有“12345”、“45123”等等。给定两个字符串&#xff0c;判断是否为旋转词。 输入描述: 输出包含三行&#xff0c;第一个两个…

2021-03-04

为什么nginx转发后端默认使用1.0而不是1.1 在 Nginx 的官网文档中&#xff0c;有这样一个指令&#xff1a; Syntax: gzip_http_version 1.0 | 1.1; Default: gzip_http_version 1.1; Context: http, server, location Sets the minimum HTTP version of a request required to…

字符串题目---2判断两个字符串是否为变形词

题目描述 给定两个字符串str1和str2&#xff0c;如果str1和str2中出现的字符种类出现的一样且每种字符出现的次数也一样&#xff0c;那么str1和str2互为变形词。请判断str1和str2是否为变形词 输入描述: 输入包括3行&#xff0c;第一行包含两个整数n&#xff0c;m(1 \leq n,…

设计模式7----代理模式

代理模式 概念 Proxy 模式又叫做代理模式&#xff0c;是结构型的设计模式之一&#xff0c;它可以为其他对象提供一 种代理&#xff08;Proxy&#xff09;以控制对这个对象的访问。 所谓代理&#xff0c;是指具有与代理元&#xff08;被代理的对象&#xff09;具有相同的接口的…

网络基础3-1(细谈IP协议头, 网络层,子网划分,路由选择,数据链路层,以太网帧格式,MAC地址,再谈ARP协议)

IP协议 IP协议头格式 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是44位头部长度(header length): IP头部的长度是多少个。32bit, 也就是 length * 4 的字节数. 4bit表示大 的数字是15, 因此IP头部大长度是60字节8位服务类型(Type Of Service): 3位优先权字段(已…

c++常见并且必须记住的问题

一、基础知识 基本语言 1、说一下static关键字的作用 ​2、说一下C和C的区别 3、说一说c中四种cast转换 4、请说一下C/C 中指针和引用的区别&#xff1f; 5、给定三角形ABC和一点P(x,y,z)&#xff0c;判断点P是否在ABC内&#xff0c;给出思路并手写代码 6、怎么判断一个…

网络中典型协议--(DNS,输入url后, 发生的事情. ,ICMP,NAT)

DNS&#xff08;Domain Name System&#xff09; DNS是一整套从域名映射到IP的系统 域名服务器发展背景 TCP/IP中使用IP地址和端口号来确定网络上的一台主机的一个程序. 但是IP地址不方便记忆. 于是人们发明了一种叫主机名的东西, 是一个字符串, 并且使用hosts文件来描述主机…

高级IO--1 ---(五种典型IO,阻塞IO,非阻塞IO,信号驱动IO,异步IO, IO多路转接)

高级IO&#xff1a; 五种典型IO&#xff1a; 阻塞IO/非阻塞IO/信号驱动IO/异步IO/IO多路转接 IO多路转接模型&#xff1a;select/poll/epoll 五种典型IO 阻塞IO IO操作的流程&#xff1a;等待IO操作条件具备&#xff0c;然后进行数据拷贝 为了完成IO操作发起调用&#xff…

IO多路转接模型----(select的模型,select的优缺点,poll的模型,poll的优缺点)

IO多路转接模型&#xff1a;select/poll/epoll 对大量描述符进行事件监控(可读/可写/异常) select模型 用户定义描述符的事件监控集合 fd_set&#xff08;这是一个位图&#xff0c;用于存储要监控的描述符&#xff09;; 用户将需要监控的描述符添加到集合中&#xff0c;这个描…

IO多路转接模型-----epoll

epoll&#xff1a; Linux下性能最高的多路转接模型 epoll 有3个相关的系统调用. epoll_create 功能&#xff1a;创建epoll&#xff0c;在内核中创建eventpoll结构体&#xff0c;size决定了epoll最多监控多少个描述符&#xff0c;在Linux2.6.8之后被忽略&#xff0c;但是必须…

再写顺序表(c语言实现,外加冒泡排序,二分查找)

概念 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。在数组 上完成数据的增删查改。 顺序表一般可以分为&#xff1a; 静态顺序表&#xff1a;使用定长数组存储。动态顺序表&#xff1a;使用动态开辟的数组存储。 头…

再写单链表(不带头单链表)

单链表 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 单向、双向带头、不带头循环、非循环 虽然有这么多的链表的结构&#xff0c;但是我们实际中最常用还是两种结构&#xff1a; 无头单向非循环链表&#xff1a;结构简单&#xff0…

再写双向循环链表

#pragma once #include<assert.h> #include<malloc.h> #include<stdio.h> typedef int DLDataType;//定义链表结点结构 typedef struct DListNode{DLDataType value;struct DListNode *prev; //指向前一个结点struct DListNode *next; //指向后一个结点 } DL…

链表题目--1 删除链表中所有等于val的值

注意事项 要删除的结点相邻第一个结点就是要删除的结点 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val){if(headNULL){return NULL;}struct …

链表题目--2 求链表的中间结点 和 求链表中倒数第k个结点

求链表的中间结点 思路 一个走两步&#xff0c;一个走一步。一个走到尾&#xff0c;另外一个就走到了中间 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* middleNode(struct ListNode* head…

链表题目---3 合并两个有序单链表 和 分割链表

合并两个有序单链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){if(l1 NULL){return l2;}else if(l2 NULL){return l1;}struc…

链表题目---4 删除链表中重复的结点 和 判断链表是否为回文链表

删除链表中重复的结点 /* struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} }; */ class Solution { public:ListNode* deleteDuplication(ListNode* pHead){if(pHead NULL){return NULL;}ListNode *prev NULL; //用于删除的结点, 是…

链表题目----5 相交链表 和 环形链表 和 返回链表开始入环的第一个节点

相交链表 思路 链表交叉不可能是x型因为有可能两个链表不等长&#xff0c;所以我们必须让他们从同一起跑位置去起跑从同一起跑位置出发&#xff0c;依次比较每个结点的地址是否相同 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct L…

链表题目---6 复制带随机指针的链表

思路 将新结点放在老结点的后面 复制random 将链表拆开 /* // Definition for a Node. class Node { public:int val;Node* next;Node* random;Node() {}Node(int _val, Node* _next, Node* _random) {val _val;next _next;random _random;} }; */ class Solution { publi…

括号匹配问题(c和c++版本实现)

括号匹配问题 思路 遇见左括号入栈&#xff0c;遇见一个右括号弹出栈顶元素右括号入栈前如果栈已经为空&#xff0c;则不匹配如果不为空则读取并弹出&#xff0c;弹出来的元素与右括号做比较&#xff0c;必须匹配&#xff0c;不匹配返回false;如果最后栈里还有元素&#xff0c…