当前位置: 首页 > news >正文

TCP相关细节

1. 常用TCP参数

1.1 ReceiveBufferSize
ReceiveBuffersize指定了操作系统读缓冲区的大小, 默认值是8192(如图5-10 所示)。在第4章的例子中,会有"假设操作系统缓冲区的长度是8" 这样的描述,可通过socket.ReceiveBufferSize= 8 实现。当接收端缓冲区满了的时候,发送端会暂停发送数据,较大的缓冲区可以减少发送端暂停的概率, 提高发送效率

1.2 SendBufferSize
SendBuffersize 指定了操作系统写缓冲区的大小,默认值也是8192。对于那些没有处 理 好 “ 完整发送数据 ” 的网络模块 ( 见 4 . 5 节 ), 可以将SendBuffersize设成较大的值 , 以避免因发 送不完整而带来的各种问题 ( 图 5 - 1 0 )。 笔者见过有些还算成功的游戏项目 , 虽没有处理好数据的接收问题,但将 Sen dBuffer si ze 调大10倍,也能让游戏正常运转。

1.3 NoDelay
指定发送数据时是否使用Nagle 算法,对于实时性要求高的游戏,该值需要设置成 true Nagle 是一种节省网络流量的机制,默认情况下,TCP 会使用Nagle 算法去发送数据。
Nagle 算法的机制在于,如果发送端欲多次发送包含少量字节的数据包时,发送端不 会立马发送数据,而是积攒到了一定数量后再将其组成一个较大的数据包发送出去。
启用Nagle 算法可以提升网络传输效率,但它要收集到一定长度的数据后才会把它们 一 块儿发送出 去。这样一来,就 会降低网 络的实时性, 大部分实时网络游戏都会关闭 Nagle 算法,将socket.NoDelay 设置成true

1.4 TTL

TTL 指发送的IP数据包的生存时间值 (Time To Live , TTL ) 。 TTL 是 IP 头部的一 个值 ,
该值表示一个IP 数据报能够经过的最大的路由器跳数。发送数据时, TTL 默 认为64 (TTL 的默认值和操作系统有关,Windows
Xp默认值为128,Windows7默认值为64, Window10 默认值为6 5, Lin ux 默认值为 255 )。

数据在网络上传输, 实际上是经过多个路由器转发的。如图5- 13所示,发送端往接收端 发送一个卫数据报,初始的TTL
为64,在经过第一个理由器时,『头部的TTL减小,变成 63;
在经过第二个路由器时,变成了62。以此类推,直到TTL等于0,路由器就会丟弃数据。

在这里插入图片描述
在网络游戏中, 如果某些偏远地区用户时不时无法按收数据 , 可以尝试增大TTL值 ( socket.ttl=xxx)来解决问题。

1.5 ReuseAddress

Reuse Address 即端又复用 , 让同一个端又可被多个 socket 使用 。 一 般 情 况 下, 一 个 端 又只能由一个进程独占,假设服务端程序都绑定了1234端又,若开启两个服务端程序,虽 然, 第一个开启的程序能够成功绑定端又并监听,但第二个程序会提示“
端又己经在使用 中 ” , 无 法 绑 定 端 又。 在 计 算 机 中 , 退 出 程 序 与 释 放 端 又 并 不 同 步 。 在 5. 2 . 3 节 “ T C P 连 接 的终止〞 中,我们知道TCP断开连接会经历4次挥手。4次挥手需要时间,在网络不好的情况下,程序还会多次重试。当服务端程序崩溃,但它持有的Socket 不会被立马释放,这 时候重启 服务器就会遇到“ 端 又已经在使用中”的情形。等到Socket 被释放后(这个过程 可 能 要 十 几 分钟 时 间 ) , 服 务 端 才 能 成 功 重 启 。

对于人 气爆棚的大型网游, 十几分钟的等待时间会造成很大损失,一般要求在程序崩 溃 ( 尽 管 也 不 应 该 崩 溃, 但 人 算 不
如 天 算 ) 后 立 刻 重 启 , 继 续 提 供 服 务 。 端 又 复 用 最 常 见 的 用途是, 防止服务器 重启时,
之前鄉定的端又还未释放或者程序突然退出而系统没有释放 端 又。这种情况下如果设定了端又复用,则新启动的服务器进程可以直接鄉定端又。如果
没有设 定端又复用, 绑定会失败,提示端又己经在使用中,只好等十几分钟再重试了。 设 置 端又 复 用 使 用 s o c k e t 的
Sctsocket Option 方 法 , 代 码 如 下 所 示 。

Socket socket= new socket(AddressFamily.InterNetwork, socketrype.stream, ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

尽 管端又复用能解决服务端立即重启的问题,但它存在安全隐患。 主动关闭方有可能 在下次 使用时 收到上一次连接的数据包, 包括关闭连接响应包或者正常通信的数据包, 有可能出现奇怪现象

1.6 LingerState
LingerState 的功能是设置套接字保持连接的时间。

在这里插入图片描述
服务端中,会使用 下面的代码处理客户
端主动关闭连接,即在收到长度为0 的消息
后 , 调 用 clientfd.Close()关 闭 连 接 。
在这里插入图片描述
在这里插入图片描述
发送缓冲区还有尚末发送的数据, 那么直接调用Close 关闭连接,缓冲区中的数据将被丢弃。这种关闭方式很暴力,因为对端 可 能 还 需 要 这 些 数 据。 在 服 务 端 收 到 关 闭 信 号 后 , 有没有办法先把发送缓冲区中的数据发完,再关闭连接呢 ? LingerState 就是为了解决这个问题而诞生的 。

socket.LingerState = new LingerOption(true, 10);

其中的LingerOption 带有两个参数。第一个参数是LingerState.Enabled,代表是否启用 LingerState,只有设置为true 才能生效。第二个参数是LingerState.Linger Time,指定超时 时间。如果超时时间大于0 (比如10 秒),操作系统会尝试发送缓冲区中的数据,但如果网络状况不好,超过10秒还没有发完,它还是会强制关闭连接。
如果LingerState.LingerTime设置为0,系统会一直等到数据发完才关闭连接,无论等待多长时间。开启LingerOption能够在一定程度上保证发送数据的完整性。
在这里插入图片描述
服务端进入TIME_WAIT状态后,会等待一段时间再释放自由.对于高并发的服务端,过多的TIME_WAIT会占用系统资源,不是已经好事。有时候需要减小服务器的TIME_WAIT值,以求快速释放自由

2. Close的恰当时机

Lingerstate选项可以让程序在关闭连接前发完系统缓冲区中的数据,然而,这并不代表能将所有数据发出去。

下面完善代码使连接关闭时,依然能够完整发送数据。
对于主动关闭的一方(假设调用下述Close 方法关闭连接),应判断当前是否还有正在
发送的数据 。如有 , 只将标志位 isClosing 设置为 true , 等数据发送完再关闭连 接 ; 如果没有正在发送数据,直接调用socket.Close()关闭连接。代码如下:

bool isClosing = false;//关闭连接
public void Close() {//还有数据在发送if(writeQueue.Count > 0) {isClosing = true;} else { //没有数据在发送socket.Close();}
}

由于设置了isClosing 标志位,在关闭连接的过程中,程序只负责将已有的数据发送 完,不会发送新的数据。可以在Send 方法中添加判断,假如程序处于Closing状态,不能发送信息。代码如下:

//点击发送按钮 
public void Send ( )
{if (isClosing) {return;}// 拼接字节 , 省略组装 sendBytes 的代码byte[] sendBytes = 要发送的数据 ;ByteArray ba = new ByteArray (sendBytes);writeQueue.Enqueue (ba); // sendif(writeQueue.Count == 1){socket. BeginSend(ba.bytes, ba.readIdx, ba.length, 0, SendCallback, socket);}
}        

在BeginSend 回调两数中 , 还需要判断程序是否处于isClosing状 态, 如果程序发 送完写入队列的所有数据,而且处于isClosing 状态,应调用socket.Close 关闭连接。代码如下:

public void Sendcallback(IAsyncResult ar) {// 获取state、Endsend 的处理Socket socket = (Socket) ar.AsyncState; int count = socket.EndSend(ar);// 判断是否发送完整ByteArray ba= writeQueue.First (); ba.readIdx+=count;if(count ==ba.length){ //发送完整writeQueue. Dequeue ( );ba = writeQueue.First ();}   if(ba != null){//发送不完整,或发送完整且存在第二条数据 socket. BeginSend(ba.bytes, ba.readIdx, ba.length,
0, SendCallback, socket);} else if(isClosing) {socket.Close ( );}
}

3. 心跳机制

断开连接时, 主动方会给对端发送 F I N 信 号 , 开启4 次挥手流程 。 但在某些情况下, 比如拿着手机进人没有信号的山区,更极端的,比如有人拿剪刀把网 线剪断。虽然断开了连 接 , 但主动方无法给对端发送 FIN 信号 ( 网线剪断了还能干什么? ), 对端会认为连接有效,一直占用系统资源。

游戏开发中,TCP默认的KeepAlive 机制很“ 鸡肋”,因为上述的“一段时间” 太长, 默认为2小时 。 一般会自行实现心跳机制 。心跳机制是指客户端定时 ( 比 如 每 隔 1 分 钟 ) 向 服务端发送P I N G 消 息 , 服 务 端 收 到 后 回 应 P O N G 消 息 。 服 务 端 会 记 录客 户 端 最 后 一 次 发 送 P I N G 消 息 的 时 间 , 如 果 很 久 没 有 收 到 (比 如 3 分 钟 ) , 就 假 定 连 接 不 通, 服 务 端 会 关 闭 连 接 , 释放系统资源

心跳机制也有缺点,比如在短暂的故障期间,它们可能引起一个良好连接被释放; PING和PONG消息占用了不必要的宽带; 在流量如黄金的移动网络中,会让玩家花贵更多 的流量费。

相关文章:

TCP相关细节

1. 常用TCP参数 1.1 ReceiveBufferSize ReceiveBuffersize指定了操作系统读缓冲区的大小, 默认值是8192(如图5-10 所示)。在第4章的例子中,会有"假设操作系统缓冲区的长度是8" 这样的描述,可通过socket.ReceiveBufferSize 8 实现。当接收端缓冲区满了的时…...

flutter实现UDP发送魔法包唤醒主机

魔法包 魔法包是用16进制表示的数据包,它是由固定的前缀数据(FFFFFFFFFFFF)以及固定重复次数(16次)的目标主机MAC地址组成。 假设目标主机的MAC地址是:"50:eb:f6:27:ae:a8" 那么魔法包就是[FFFFFFFFFFFF50EBF627AEA850EBF627AEA850EBF627AEA8…...

回溯算法练习题(2024/6/18)

1全排列 II 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: 输入:nums [1,1,2] 输出: [[1,1,2],[1,2,1],[2,1,1]]示例 2: 输入:nums [1,2,3] 输出:[[1,…...

DSP——从入门到放弃系列2——PLL锁相环(持续更新)

1、概述 锁相环(Phase Locked Loop,PLL)是处理器的时钟源,控制着C6678处理器中C66x内核、各外围设备的时钟的时钟比、对准和选通功能。 2、功能描述 上图显示了PLL和PLL控制器的逻辑实现。PLL控制器提供通过软件可配置的分频器&#xff0…...

Altair 人工智能技术助力MABE预测消费者行为,实现设备性能优化

主要看点 行业: 家电行业 挑战: 企业面临的挑战是如何利用已收集的大量数据,深入了解消费者在产品使用过程中对某些保鲜程序的影响。 Altair 解决方案: Altair采用了Altair RapidMiner人工智能平台来解决问题,特别是…...

解决Spring Boot项目中数据源URL属性的问题

今天测试Springboot项目的时候,报错: . ____ _ __ _ _/\\ / ____ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | _ | _| | _ \/ _ | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) ) |____| .__|_| |_|_| |_\__, | / / / /|_||___…...

Java每日作业day6.18

ok了家人们今天我们继续学习方法的更多使用,闲话少叙,我们来看今天学了什么 1.重载 在同一个类中,可不可以存在同名的方法?重载:在同一个类中,定义了多个同名的方法,但每个方法具有不同的参数类型或参数个…...

mac如何检测硬盘损坏 常用mac硬盘检测坏道工具推荐

mac有时候也出现一些问题,比如硬盘损坏。硬盘损坏会导致数据丢失、系统崩溃、性能下降等严重的后果,所以及时检测和修复硬盘损坏是非常必要的。那么,mac如何检测硬盘损坏呢?有哪些常用的mac硬盘检测坏道工具呢? 一、m…...

怎么通俗理解概率论中的c r(cramer rao 克拉默拉奥)不等式?

还是推一下比较好记 视频链接 【数理统计学重要定理证明:C-R不等式——无偏估计的方差下界-哔哩哔哩】 https://b23.tv/4gk1AvU 【数理统计学重要定理证明:C-R不等式——无偏估计的方差下界-哔哩哔哩】...

Flask之模板

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、模板的基本用法 1.1、创建模板 1.2、模板语法 1.3、渲染模板 二、模板辅助工具 2.1、上下文 2.2、全局对象 2.3、过滤器 2.4、测试…...

如何优化 Bash 脚本的执行效率?

要优化 Bash 脚本的执行效率,可以考虑以下几个方面: 减少命令执行次数:Bash 脚本中的命令执行是比较耗时的,在可能的情况下,可以尽量减少命令的执行次数。例如,可以将多个命令合并成一个,使用管…...

c语言---循环 、判断基础知识详解

if语句 else离最近的if语句结合。 if语句题目 //1. 判断一个数是否为奇数 //2. 输出1 - 100之间的奇数 #include <stdio.h> int main() {int n 0;scanf("%d", &n);if (n % 2){printf("奇数\n");}else{printf("不是奇数\n"…...

Opencv高级图像处理

文章目录 Opencv高级图像处理图像坐标二值化滤波高斯滤波中值滤波 开闭运算检测霍夫圆检测边缘检测Canny边缘检测findContours区别傅里叶变换-高/低通滤波 直线检测 相机标定视频处理视频格式 模板摄像头处理&#xff08;带参调节&#xff09;单图片处理&#xff08;带参调节&a…...

Linux操作系统学习:day03

内容来自&#xff1a;Linux介绍 视频推荐&#xff1a;[Linux基础入门教程-linux命令-vim-gcc/g -动态库/静态库 -makefile-gdb调试]( 目录 day0317、创建删除目录创建目录删除目录 18、文件的拷贝19、mv 命令20、查看文件内容的相关命令21、给文件创建软连接或硬链接 day03 …...

快排(霍尔排序实现+前后指针实现)(递归+非递归)

前言 快排是很重要的排序&#xff0c;也是一种比较难以理解的排序&#xff0c;这里我们会用递归的方式和非递归的方式来解决&#xff0c;递归来解决是比较简单的&#xff0c;非递归来解决是有点难度的 快排也称之为霍尔排序&#xff0c;因为发明者是霍尔&#xff0c;本来是命名…...

客户端输入网址后发生的全过程解析(协议交互、缓存、渲染)

目录 1. 输入 URL 并按下回车键2. DNS 解析3. TCP 连接4. 发送 HTTP 请求5. 服务器处理请求6. 发送 HTTP 响应7. 浏览器接收响应8. 渲染网页9. 执行脚本10. 处理其他资源11. TLS/SSL 加密&#xff08;如果使用 HTTPS&#xff09;握手过程 12. 协议协商和优化 总结 1. 输入 URL …...

未来科技:Web3如何重塑物联网生态系统

随着Web3技术的崛起&#xff0c;物联网&#xff08;IoT&#xff09;的发展正迎来一场深刻的变革。本文将深入探讨Web3如何重塑物联网生态系统&#xff0c;从技术原理到应用实例&#xff0c;全面解析其对未来科技发展的影响和潜力。 1. Web3技术简介与发展背景 Web3技术是建立在…...

C++之模板(二)

1、类模板 2、使用类模板 类模板在使用的时候要显示的调用是哪种类型&#xff0c;而不是像函数模板一样能够根据参数来推导出是哪种类型。 Stack.h #include <stdexcept>template <typename T> class Stack { public:explicit Stack(int maxSize);~Stack();void …...

相机的标定

文章目录 相机的标定标定步骤标定结果影响因素参数分析精度提升一、拍摄棋盘格二、提升标定精度 标定代码实现 相机的标定 双目相机的标定是确保它们能够准确聚焦和成像的关键步骤。以下是详细的标定步骤和可能的结果&#xff0c;同时考虑了不同光照条件和镜头光圈大小等因素对…...

C# 利用XejeN框架源码,编写一个在 Winform 界面上的语法高亮的编辑器,使用 Monaco 编辑器

析锦基于Monaco技术实现的Winform语法高亮编辑器 winform中&#xff0c;我们有时需要高亮显示基于某种语言的语法编辑器。 目前比较强大且UI现代化的&#xff0c;无疑是宇宙最强IDE的兄弟&#xff1a;VS Code。 类似 VS Code 的体验&#xff0c;可以考虑使用 Monaco Editor&a…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...