嵌入式linux学习笔记---TCP立即发出 以及 TCP的keep alive

news/2024/7/4 13:28:41

事情的起因是公司的产品的某一个功能存在的bug,所以就有了本次的探索。

需求: 产品在某一个端口上 定时的向外发送1440 字节的数据包,该数据包包含了产品当前的各种状态。
需求2 : 产品本身绑定一个本地的端口 接收来自外部的字符串指令,并且需要对外部传入的字符串指令进行处理。

1. TCP 立即发出

这部分使用的是 TCP_NODELAY 这个标志去实现的。
在创建完端口之后 使用以下的api 为端口设置不缓存的属性,可以实现数据的立即发出!

    int flag = 1;
    setsockopt(this->socketFd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));

效果对比:
使用这个标志之后的数据包 非常稳定 大小是 1440 + 包头 共计 1494 字节,每个数据包都是这么大!
在这里插入图片描述

如果不使用这个选项 那么会出现数据包的拼接
在这里插入图片描述
这里可以看到 我们的数据被拼接到了一起
在这里插入图片描述
在这里插入图片描述
虽然两个包 分别是 1420 + 1460 = 1440 + 1440 也就是说数据的总量是没少的,但是 这种类型的拼包显然不是我们期望的!这会造成潜在的数据错位 以及延时!

关于 TCP的立即发出 以下的博客给出了以下说法:

TCP协议栈默认开启nagle 算法来实现网络带宽的优化,可以通过以下方式关闭
//设置tcp
static void socket_set_nodelay(int fd)
{
/*Nagle算法于1984年定义为福特航空和通信公司IP/TCP拥塞控制方法,这使福特经营的最早的专用TCP/IP网络
减少拥塞控制,从那以后这一方法得到了广泛应用。Nagle的文档里定义了处理他所谓的小包问题的方法,这种问题
指的是应用程序一次产生一字节数据,这样会导致网络由于太多的包而过载(一个常见的情况是发送端的"糊涂窗口
综合症(Silly Window Syndrome)")。从键盘输入的一个字符,占用一个字节,可能在传输上造成41字节的
包,其中包括1字节的有用信息和40字节的首部数据。这种情况转变成了4000%的消耗,这样的情况对于轻负载的网
络来说还是可以接受的,但是重负载的福特网络就受不了了,它没有必要在经过节点和网关的时候重发,导致包丢失
和妨碍传输速度。吞吐量可能会妨碍甚至在一定程度上会导致连接失败。Nagle的算法通常会在TCP程序里添加两行
代码,在未确认数据发送的时候让发送器把数据送到缓存里。任何数据随后继续直到得到明显的数据确认或者直到攒
到了一定数量的数据了再发包。尽管Nagle的算法解决的问题只是局限于福特网络,然而同样的问题也可能出现在
ARPANet。这种方法在包括因特网在内的整个网络里得到了推广,成为了默认的执行方式,尽管在高互动环境下有些
时候是不必要的,例如在客户/服务器情形下。在这种情况下,nagling可以通过使用TCP_NODELAY 套接字选项关
闭。*/
int flag = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
}
————————————————
版权声明:本文为CSDN博主「zhaoforyou」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhaoforyou/article/details/53590096

2. TCP 的 keepAlive

这个选项主要是用于确保TCP 客户端的存在的, 我们的产品的控制对实时性要求很高,所以也就是需要及时的感知到客户端的掉线事件,在之前的开发中一直存在一种情况,就是如果客户端不是很 “优雅” 的断开了连接(比如直接断开网线 或者直接干掉了进程) 那么我们的服务端是无法感知到客户端的掉线的,而产品为了安全性的考虑,同一时刻只允许一个客户端进行连接,这样也就导致的我们的客户端如果掉线之后也没法重新连接到产品!!! 这是非常严重的一个问题!

所以我们引入了严格的掉线检测机制:
如果1s 之内没有交互数据就回去下发心跳的请求,两次心跳请求间隔为1s 如果连续三次没有心跳 那么久判定客户端掉线!

相关的代码段如下 :


#include <netinet/tcp.h>   // 这是需要包含的头文件
// ....... 创建socket等操作
    int keepAlive = 1;     // 开启keepalive属性
    int keepIdle = 1;      // 如该连接在1秒内没有任何数据往来,则进行探测 
    int keepInterval = 1;  // 探测时发包的时间间隔为1 秒
    int keepCount = 3;     // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.

    setsockopt(this->socketFd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
    setsockopt(this->socketFd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
    setsockopt(this->socketFd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
    setsockopt(this->socketFd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount)); 
    // ....  绑定  监听 接受等操作

http://www.niftyadmin.cn/n/3018940.html

相关文章

Flink Sort-Shuffle写简析

文章目录1、配置2、初始创建3、成员变量4、写shuffle文件4.1、获取SortBuffer4.2、追加数据4.3、buffer不足的处理4.4、buffer不足数据未读完5、关于排序5.1、segment申请5.2、writeIndex5.2.1、获取当前可用segment5.2.2、写入index到segment5.2.3、更新partition最后数据的索…

Flink Sort-Shuffle读简析

文章目录1、SortMergeResultPartition的创建使用2、PartitionedFileReader2.1、moveToNextReadableRegion2.2、readCurrentRegion2.3、hasRemaining3、读操作的调用4、数据返回4.1、读入缓存4.2、buffersRead读取1、SortMergeResultPartition的创建使用 首先是一个读过程的一个…

信息社会

消息 通知 公告(简报) 新闻(深度分析文章) 历史(沉淀形成知识) 各部门的信息系统 陕西省住房和城乡建设厅 陕西省建筑市场监管平台陕西省质量安全监管信息系统陕西省标准定额协同管理平台陕西省房地产市场监管信息系统陕西省城市园林绿化企业信息管理系统陕西省执业资格注册人员…

java 实现方法_java常见代码(1)------常见实现方法

1.equals 和 hashcode方法class Students {String name;int age;byte[] idSequence;Overridepublic boolean equals(Object obj) {if (!(obj instanceof Students))return false;Students other (Students) obj;return name.equals(other.name)&& age other.age&…

JdbcSink 简析

文章目录1、JdbcSink1.1、参数1.2、返回2、JdbcBatchingOutputFormat2.1、参数2.2、open方法2.2.1、连接数据库2.2.2、JdbcExec2.2.3、scheduler2.3、writeRecord方法2.3.1、缓存数据2.3.2、flush1、JdbcSink 用于DataStream增加Jdbc的Sink输出&#xff0c;主要两个接口&#x…

机器学习(1)_R与神经网络之Neuralnet包

本篇博客将会介绍R中的一个神经网络算法包&#xff1a;Neuralnet&#xff0c;通过模拟一组数据&#xff0c;展现其在R中是如何使用&#xff0c;以及如何训练和预测。在介绍Neuranet之前&#xff0c;我们先简单介绍一下神经网络算法。 人工神经网络(ANN)&#xff0c;简称神经网络…

C# List.ForEach 方法

C#中List.ForEach 方法是对 List 的每个元素执行指定操作。 示例&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace AppExample {class Program{static void Main(string[] args){…

Adaptive调度器

文章目录1.前言2.测试3.配置启用4.其他配置参数4.1.主要配置4.2.其他可能相关的配置5.调用流程6.配置Adaptive调度器7.DefaultDeclarativeSlotPool7.1.NewSlotsListener7.2.offerSlots7.3.freeReservedSlot7.4.缩容触发8.AdaptiveScheduler8.1.使用条件8.2.计算并行度信息8.2.1…