sokcet常用配置

news/2024/7/3 0:39:47

非阻塞模式

套接字有两种工作模式:

  • 阻塞模式: 阻塞调用是指调用结果返回之前,当前线程会被挂起。该进程被标记为睡眠状态并被调度出去。函数只有在得到结果之后才会返回。当socket工作在阻塞模式的时候, 如果没有数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止。
  • 非阻塞模式: 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。epoll工作在非阻塞模式时,才会发挥作用。

正常情况下,socket工作在阻塞模式下,在调用accept,connect,read,write等函数时,都是阻塞方式,直到读到数据才会返回。但是,如果将socket设置为非阻塞状态,那么这么些函数就会立即返回,不会阻塞当前线程。
设置非阻塞socket的方法是:

int flags = fcntl(app_socket->fd, F_GETFL, 0);
flags |= O_NONBLOCK;
flags |= O_NDELAY;
fcntl(app_socket->fd, F_SETFL, flags);

建立连接

客户端调用 connect() 发起对服务端的 socket 连接,
如果客户端的 socket 描述符为阻塞模式,则 connect() 会阻塞到连接建立成功或连接建立超时
(Linux 内核中对 connect 的超时时间限制是 75s, Soliris 9 是几分钟,因此通常认为是 75s 到几分钟不等)。

如果为非阻塞模式,则调用connect()后函数立即返回,如果连接不能马上建立成功(返回 -1),则 errno 设置为 EINPROGRESS,此时 TCP 三次握手仍在继续。此时可以调用 select() 检测非阻塞 connect 是否完成。select 指定的超时时间可以比 connect 的超时时间短,因此可以防止连接线程长时间阻塞在 connect 处。

处理非阻塞 connect 的步骤:

  1. 创建socket,并利用fcntl将其设置为非阻塞。
  2. 调用connect函数,如果返回0,则连接建立;如果返回-1,检查errno ,如果值为 EINPROGRESS,则连接正在建立。
  3. 为了控制连接建立时间,将该socket描述符加入到select的可写集合中,采用select函数设定超时。
  4. 如果规定时间内成功建立,则描述符变为可写;否则,采用getsockopt函数捕获错误信息。当errno == 0表示只可写。

源自Berkeley的实现(和Posix.1g)有两条与select和非阻塞IO相关的规则:
A: 当连接建立成功时,套接字描述符变成可写;
B: 当连接出错时,套接字描述符变成既可读又可写;

所以对于 非阻塞模式connect() 的判断逻辑如下:

 1. connect()返回值为0,连接成功。
 2. connect()返回值不为0,且 errno 的值也不为EINPROGRESS,表示连接失败。
 3. connect()返回值不为0,但是 errno 为EINPROGRESS,则使用 select 进行下一步判断。
 	3.1 如果 select() 返回 0,表示在 select() 超时时间内未能成功建立连接。
 	3.2 如果 select() 小于 0,表示连接失败。
 	3.3 如果 select() 大于 0,表示检测到存在变化套接字描述符。
 		3.3.1 如果套接字描述符不可写,则连接失败。
 		3.3.2 如果套接字描述符变成可写,连接成功。
 		3.3.3 如果套接字描述符变成可读可写,采用getsockopt函数捕获错误信息。当errno == 0表示只可写,连接成功,否则连接失败。
 		3.3.4 [可选]可以再次进行connect()连接,如果返回值为EISCONN,则认为已经连接

断开连接

当select检测到套接字描述符可写,但是接收到数据为0时,认为是断开连接。

if(select(fd_max + 1, &read_set, NULL, NULL, &time)>0) {
	if(FD_ISSET(app_socket->fd, &read_set) ){
		recv_len = read(app_socket->fd, buff, 100);
		if (recv_len == 0){
            // Socket 断开
        }
        else{
            int ret = lwip_get_error(app_socket->fd);
            if (ret != EAGAIN && ret != EINTR){
                // Socket 断开
            }
        }
    }
}

配置

int reuseaddr = 1; // 允许重用本地地址和端口
setsockopt(app_socket->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&reuseaddr, sizeof(reuseaddr));

int keepalive = 1;     // 开启keepalive属性
int keepidle = 60;     // 如果连接过程中20s没有数据就发送一个探测包
int keepcount = 3;     // 一共发送探测包次数,期间收到回复就不再发送下一次的探测包
int keepinterval = 10; // 探测包的时间间隔为10s
setsockopt(app_socket->fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(keepalive));
setsockopt(app_socket->fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepidle, sizeof(keepidle));
setsockopt(app_socket->fd, IPPROTO_TCP, TCP_KEEPCNT, (void *)&keepcount, sizeof(keepcount));
setsockopt(app_socket->fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepinterval, sizeof(keepinterval));

http://lihuaxi.xjx100.cn/news/327546.html

相关文章

HikariCP实战 | 通过查看源码分析如何解决maxLifeTime配置问题

目录1、追本溯源2、解决hikariCP的maxLifetime配置出现以下warn问题3、具体解决步骤(查看源码)1、追本溯源 很多年前在stackoverflow上写过一篇文章: https://stackoverflow.com/questions/28180562/hikaricp-and-maxlifetime# hikariCP是非…

基于web的老年保健品销售系统/保健品销售系统

摘 要 为了解决用户便捷地在网上购物,本文设计和开发了一个老年保健品销售系统。本系统是基于web架构设计,SSM框架 ,使用Mysql数据库管理,综合采用JSP模式来完成系统的相关功能。主要实现了管理员与用户的注册与登陆&#xff0…

计算机毕业设计Java汽车售后服务管理系(源代码+数据库+系统+lw文档)

计算机毕业设计Java汽车售后服务管理系(源代码数据库系统lw文档) 计算机毕业设计Java汽车售后服务管理系(源代码数据库系统lw文档)本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件:idea eclipse 前端技术&#xf…

Polygon zkEVM中的子约束系统

1. 引言 前序博客有: Polygon zkEVM工具——PIL和CIRCOM Polygon zkEVM中主要设计了3种子约束系统: 1)Permutation check子约束系统:PIL中的关键字为is。 2)Plookup 子约束系统:PIL中的关键字为in。 …

d原子是无锁的吗

原文 文档说: 原子方式加mod到val引用的值,并返回先前val保存的值.此操作是无锁且原子的. 查看实现是: lock; xadd[%0], %1;真是无锁的吗?可用cas来替换吗?伪码: int atomicFetchAdd(int * pAddr, int nIncr ) {while (true) {int ncur atomicLoad(pAddr);if (cas( pAddr,…

OpenStack 创建虚拟机错误: Host ‘compute1‘ is not mapped to any cell

之前 Ubuntu 20.04 手动安装OpenStack只做到了 Networking service Installation Guide 这一步,然后就不继续了,以为最困难的都过去了 今天临时想要创建一个虚拟机,发现从命令行方式和 DashBoard 创建虚拟机,都报错了&#xff01…

java招投标系统 招投标系统简介 招投标系统源码

随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及审计监督要…

[附源码]Python计算机毕业设计Django校园疫情管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…