.Net 下通过缓存提高TCP传输速度

Nginx性能优化:TCP协议深度解析与实践指南 TCP协议作为网络通信的核心基础,通过三次握手建立可靠连接,并利用滑动窗口机制实现流量控制。在Web服务器领域,这些底层机制直接影响着Nginx等高性能服务器的吞吐量和响应速度。通过调整TCP窗口参数、优化连接队列等内核级配置,工程师可以显著提升静态资源传输效率,这在电商大促、视频流媒体等高并发场景中尤为重要。Nginx作为反向代理服务器,其reuseport、tcp_nodelay等特性与TCP协议深度协同,配合BBR拥塞控制算法,能够有效应对网络延迟和丢包问题。本文通过真实案例展示如何通过TCP状态监控 阅读详情

来自:http://www.cnblogs.com/eaglet/archive/2009/11/04/1595887.html

 .Net 提供了一个NetworkStream 用于TCP 的读写,实际使用时发现直接操作效率很低,哪怕把TCP 的发送缓存和接受缓存设置很大也没有太大提高。后来在对 NetworkStream 读写前设置了缓存,性能一下子提高了很多。

    从实际测试结果看设置自己的写缓存,对性能的提升最为显著。我分析了一下,其原因很可能是在向NetworkStream 序列化对象时,序列化程序调用了大量的Write 方法向NetworkStream写入数据,每次向NetworkStream写入数据,数据被首先写入TCP的发送缓存,并且由调用线程设置一个信号通知.Net framework 内部的TCP线程发送缓冲区中已经有数据,TCP线程被激活并读取发送缓冲区中的数据,组包并向网卡写入数据。频繁的调用 NetworkStream.Write 写入小块数据将导致调用线程和TCP线程反复切换,并大量触发网卡中断,导致发送效率低下。如果我们在发送前将数据缓存并按较大的数据块发送给TCP线程,则大大减少线程切换和网卡中断数量,从而大大提高传输效率。

    问题到这里还没有结束,我们发送的对象往往较大,如果我们将发送对象全部序列化到buffer中再发送,那么势必占用大量内存,实际上我们无法忍受这种对内存无限制申请的行为,试想一个1G大小的对象,我们在发送前为它另外再开辟1个G的内存来缓存,对于系统来说简直是无法忍受。由于我们用.net 发送数据,我们在发送时需要将对象序列化到流中,而不能像 C/C++那样直接通过指针来读取数据(当然你也可以用unsafe代码,但这种方式会带来其他问题,而且并不为大家所推荐),所以我们需要开发一个专门用 TCP 发送缓存的流来处理读写前的缓存。为此我开发了一个 TcpCacheStream 类,这个类被用在读写 NetworkStream 前先进行缓存。

    调用方法很简单

   

  • 发送过程
object msg;
//初始化 msg 过程省略
System.Net.Sockets.NetworkStream _ClientStream;
//初始化 _ClientStream 过程省略
 
//创建TcpCacheStream 
TcpCacheStream tcpStream = new TcpCacheStream(_ClientStream);
 
//二进制序列化 msg 对象到 TcpCacheStream 
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(tcpStream, msg);
 
//将缓存中最后一包的数据发送出去
tcpStream.Flush();

  

  • 接收过程
 
System.Net.Sockets.NetworkStream _ClientStream;
//初始化 _ClientStream 过程省略
 
//创建TcpCacheStream 
TcpCacheStream tcpStream = new TcpCacheStream(_ClientStream);
 
//从 TcpCacheStream 二进制反序列化
IFormatter formatter = new BinaryFormatter();
objcet result = formatter.Deserialize(tcpStream);

TcpCacheStream 类为调用者封装了缓存的过程,这个缓存过程实际并不复杂,发送时数据先写入TcpCacheStream的buf中,当buf满后才向NetworkStream 写入数据,否则只缓存。由于最后一包不能保证正好填满buf,我们在写入数据后一定要调用 Flush 方法,将所有数据都发送出去。接收的过程反过来,如果buf中没有数据,就先将数据读入到buf中,然后再COPY给调用者,如果已经有数据则直接COPY给调用者。

 

TcpCacheStream 的代码如下:

    [Serializable]
    public class TcpCacheStream : Stream
    {
        #region Private fields
        const int BUF_SIZE = 4096;
        private byte[] _Buf = new byte[BUF_SIZE];
 
        private MemoryStream _CacheStream = new MemoryStream(BUF_SIZE);
        private NetworkStream _NetworkStream;
 
        private int _BufLen = 0;
 
        #endregion
 
        #region Private properties
 
        private MemoryStream CacheStream
        {
            get
            {
                return _CacheStream;
            }
        }
 
        #endregion
 
 
        #region Public properties
 
        /// <summary>
        /// get or set the Network Stream
        /// </summary>
        public NetworkStream NetworkStream
        {
            get
            {
                return _NetworkStream;
            }
        }
 
        #endregion
 
 
        public TcpCacheStream(NetworkStream networkStream)
        {
            _NetworkStream = networkStream;
        }
 
        #region Implement stream class
 
        public override bool CanRead
        {
            get
            {
                return true;
            }
        }
 
        public override bool CanSeek
        {
            get
            {
                return false;
            }
        }
 
        public override bool CanWrite
        {
            get
            {
                return true;
            }
        }
 
        public override void Flush()
        {
            NetworkStream.Write(_Buf, 0, _BufLen);
            NetworkStream.Flush();
        }
 
        public override long Length
        {
            get
            {
                throw new Exception("This stream can not seek!");
            }
        }
 
        public override long Position
        {
            get
            {
                throw new Exception("This stream can not seek!");
            }
 
            set
            {
                throw new Exception("This stream can not seek!");
            }
        }
 
        public override int Read(byte[] buffer, int offset, int count)
        {
            int len = 0;
 
            //If cache is not empty, read from cache
            if (CacheStream.Length > CacheStream.Position)
            {
                len = CacheStream.Read(buffer, offset, count);
                return len;
            }
 
            //Fill cache
            len = NetworkStream.Read(_Buf, 0, BUF_SIZE);
 
            if (len == 0)
            {
                return 0;
            }
 
            CacheStream.Position = 0;
            CacheStream.Write(_Buf, 0, len);
            CacheStream.SetLength(len);
            CacheStream.Position = 0;
 
            len = CacheStream.Read(buffer, offset, count);
 
            return len;
        }
 
        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new Exception("This stream can not seek!");
        }
 
        public override void SetLength(long value)
        {
            throw new Exception("This stream can not seek!");
        }
 
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (offset + count > buffer.Length)
            {
                throw new ArgumentException("Count + offset large then buffer.Length");
            }
 
            int remain = count - (BUF_SIZE - _BufLen);
 
            if (remain < 0)
            {
                Array.Copy(buffer, offset, _Buf, _BufLen, count);
                _BufLen = BUF_SIZE + remain;
            }
            else
            {
                Array.Copy(buffer, offset, _Buf, _BufLen, BUF_SIZE - _BufLen);
                NetworkStream.Write(_Buf, 0, _Buf.Length);
 
                Array.Copy(buffer, offset + BUF_SIZE - _BufLen, _Buf, 0, remain);
 
                _BufLen = remain;
            }
        }
 
        #endregion
    }

Nginx性能调优手册:从worker_processes到TCP优化全解析 本文深入解析Nginx性能调优的核心策略,涵盖worker_processes进程绑定、TCP连接优化、缓冲区调整及系统级参数配置。通过实战压测数据对比,详细阐述了如何通过精准配置提升高并发场景下的吞吐量与响应速度,实现从应用到系统的全链路性能优化。 阅读详情

相关推荐

TCP三次握手与四次挥手原理详解

TCP协议作为网络传输层的核心协议,其可靠性建立在连接状态的精确管理上。三次握手通过交换初始序列号(ISN)实现通信双方的状态同步,解决了分布式系统在不可靠网络环境下的共识问题。四次挥手则因TCP全双工特性需要分别关闭两个方向的连接,确保数据传输的完整性。TIME_WAIT状态的设计既保证了连接可靠终止,又避免了旧报文干扰新连接。这些机制共同构成了TCP可靠传输的基础,广泛应用于HTTP、HTTPS等互联网协议中,是网络编程和系统调优必须掌握的核心知识。

weixin_34367257的博客 357

TCP性能和发送接收窗口、Buffer的关系

TCP性能和发送接收窗口、Buffer的关系 | plantegg

jusu10的博客 1182

NFS 性能调优实战:调整 4 个内核参数与挂载选项提升 30% 传输速度

本文详细介绍了NFS性能调优的实战方法,通过调整4个关键内核参数与挂载选项,可显著提升30%的传输速度。内容涵盖NFS性能瓶颈诊断、核心调优参数解析、系统级深度调优及生产环境配置示例,帮助运维团队优化Linux环境下的Network File System性能。

weixin_34025051的博客 672

常见的网络命令

Ping命令: ping命令通过发送ICMP回声请求报文来检查与另一个计算机的连接。 这是一个用于排除连接故障的测试命令,如果不带参数则显示帮助信息。 ping命令的语法如下: C:/>ping /? 用法: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS] [-r c

愿世界和平的IT劝退师 4411

TCP协议深度解析:从三次握手到拥塞控制的网络传输核心机制

TCP(传输控制协议)是互联网可靠数据传输的基石,其核心在于通过序列号、确认应答和重传机制保障数据的有序、无差错交付。协议通过滑动窗口实现流量控制,匹配收发双方的速率;通过拥塞控制算法(如Reno、CUBIC)动态探测网络带宽,避免网络过载。这些机制共同构成了TCP的可靠传输能力,对网络性能调优、高并发服务架构设计至关重要。本文聚焦于TCP连接管理中的三次握手与四次挥手,深入解析其状态变迁与设计哲学,并结合Wireshark抓包和Linux内核参数调优,探讨TIME_WAIT状态、快速重传、SACK等工程实

weixin_34357436的博客 418

CMake接口库实战:如何用add_library的INTERFACE选项管理跨项目依赖

本文深入探讨了CMake中add_library的INTERFACE选项在管理跨项目依赖时的实战应用。通过创建不包含源代码的接口库,开发者可以集中管理头文件路径、编译定义、链接库等公共配置,并将其声明式地传递给依赖目标。文章以构建模块化跨平台网络应用为例,详细展示了如何利用接口库实现配置的集中化、依赖关系的显式化,从而提升大型项目的可维护性和可移植性。

water的专栏 1039

流缓冲区的特化版本(适用于通用tcp业务包)

这是c++标准库的流缓冲区接口 http://www.cplusplus.com/reference/streambuf/streambuf/ 基本理念是使用游标标识缓冲区的读写点,让缓冲区尽量以惰性扩容和减容来减少性能开支. 一下是我的特化版本的的主体结构 // Ethernet len[46~1500] MTU 20  // udp head  8 1500 - 20 -  

mm_longcheng的专栏 385

BugkuCTF-PWN题pwn2-overflow超详细讲解

解题思路 1)计算出get_shell_的地址偏移量 2)算出来之后就直接溢出到后门函数 知识点 x64函数调用规则 解题之前我们先学下linux x64的函数调用规则。 x64机器在调用某个函数前,比如int func(int a, int b, int c, int d, int e, int f, int g, int h),首先他会把前6个参数从左往右存入到寄存器rdi、rsi、rdx、rcx、r8、r9,其余参数存入到栈里,保存的顺序是从右往左入栈。比如abcdef会存入到寄存器里,然后一次入栈h

am_03的博客 3013

C# .Net 下通过缓存提高TCP传输速度

       .net 提供了一个NetworkStream 用于TCP 的读写,实际使用时发现直接操作效率很低,哪怕把TCP 的发送缓存和接受缓存设置很大也没有太大提高。后来在对 NetworkStream 读写前设置了缓存,性能一下子提高了很多。  从实际测试结果看设置自己的写缓存,对性能的提升最为显著。我分析了一下,其原因很可能是在向NetworkStream 序列化对象时,序列化程序调

ssihc0的专栏 5862

SquareLine Studio汉化版安装激活全攻略:LVGL嵌入式UI设计从入门到出代码

嵌入式GUI开发中,LVGL作为轻量级开源图形库,广泛应用于STM32、ESP32等MCU平台。可视化设计器通过拖拽生成LVGL代码,大幅提升UI开发效率。SquareLine Studio正是这类工具的代表,支持界面设计、事件绑定与代码导出。其安装、汉化与激活是初学者常见门槛,尤其涉及LVGL版本匹配、字体配置及FreeRTOS移植等关键环节。本文围绕汉化版安装、一个月免费激活码使用及最小可用流程展开,帮助开发者快速上手LVGL界面设计,规避常见环境与集成问题。

weixin_29189987的博客 409

用Cursor+Node.js零代码搭建健康数据仪表盘:从数据录入到可视化全流程

本文详细介绍了如何利用Cursor AI编程助手和Node.js,无需手动编写代码,即可构建个人健康数据仪表盘的全流程。通过自然语言指令,实现从数据录入、存储到动态图表可视化的完整系统,展示了AI驱动开发在降低技术门槛、提升开发效率方面的强大能力。

gitlab7runner的博客 698

深度解析 Linux 内核参数 net.ipv4.tcp_rmem:优化网络性能的关键

net.ipv4.tcp_rmem 是 Linux 内核中控制 TCP 接收缓冲区大小的关键参数,由最小值、默认值和最大值三个值组成,分别影响网络通信的稳定性、初始性能和最大传输效率。合理配置该参数可以显著提升网络性能,适用于高并发 Web 服务器、文件传输服务和实时通信应用等场景。通过 sysctl 命令可以查看和临时调整该参数,而永久修改则需编辑 /etc/sysctl.conf 文件。调整时需注意内存资源限制、网络环境适配以及与其他网络参数的协同作用。实际测试表明,过小的缓冲区会频繁触发流量控制,严重

lyndon 2668

学Simulink--基于电力电子变换器的建模与仿真实例:LLC谐振变换器在高频AC-DC转换中的建模

本文详细介绍了使用Simulink+Simscape Electrical对LLC谐振变换器进行建模与仿真的完整流程。LLC谐振变换器因其高效率、低噪声的特点,广泛应用于高频AC-DC转换场景。文章从背景原理出发,逐步讲解系统结构设计、建模步骤(包括AC源、整流器、LLC变换器、负载等模块搭建)、控制策略实现(固定频率/变频/PID控制)和仿真设置。通过分析仿真结果的关键指标,提出参数整定和算法优化建议。该建模方法为电力电子设计人员提供了实用的仿真工具,有助于优化LLC变换器性能,缩短开发周期。

xiaoheshang_123的博客 296

TCP参数调优:跨境链路上改哪几个内核参数最管用

跨境传输速度上不去,很多时候不是带宽不够,是TCP协议栈的参数没调对。默认配置是为低延迟、低丢包的网络设计的,放到跨太平洋链路上就是水土不服。调哪些参数能明显改善速度,列几个实测有效的方向。

Bobolink_的博客 592

【linux】linux 出现一个网卡绑定多个ip怎么处理

我的原因是我使用了dhcp,这个会自动分配ip, 将 BOOTPROTO 参数由 dhcp 改为 static,并移除或注释掉与动态分配地址 10.0.2.15 相关的配置行(如果存在)。执行后,您可以再次使用 ip -4 a 或 ifconfig 命令确认 IP 地址已被移除。输出可以看出,您的虚拟机(k8s003)中存在一个名为 enp0s3 的网卡绑定了多个 IPv4 地址。对于某些 Linux 发行版(如 Ubuntu、Debian),您可能需要编辑网络接口的配置文件来移除多余的 IP 地址。

九师兄 297

APM32取代STM32的经验分享

我仔细检查了代码中与硬件相关的部分,例如外设寄存器的访问和中断处理程序的设置,并进行了相应的修改。在本文中,我将分享我将APM32引入项目中取代STM32的经验,并提供相应的源代码。我查看了APM32的官方网站、开发者论坛和相关社交媒体,了解了开发者社区的活跃度和可用的资源。总结起来,将APM32替换STM32的过程需要经过几个关键步骤:了解APM32的规格和功能、评估软件生态系统、迁移代码和调试,以及性能和功耗优化。在开始替换之前,我对APM32进行了详细的研究和评估,以确保它能够满足项目的需求。

UplKubernetes的博客 2004

构建高性能的ASP.NET应用(五)

既然我们讲的是如何构建高性能的ASP.NET站点应用,那么我们就开始涉及网站方面的东西。我们说过,我们会把关注点放在“调优”上面。 在调优的时候,我们没有必要把事情搞的很复杂,要“由表及里。从整体到局部”。对于一个站点而言,我们最直接看到的就是网站的页面。换句话说,如果站点性能处理问题,肯定在页面上面会有反应。一个最显而易见的反应就是:页面加载很慢,半天看不到内容。 此时,我们可以进一步的分析

萌萌的It人 www.itmmd.com 948

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Nginx缓存机制解析与性能优化实践

Web缓存技术通过存储频繁访问的资源副本,显著提升系统响应速度并降低服务器负载。其核心原理包括缓存命中、失效策略和存储层次结构设计,在构建高并发系统中具有重要价值。Nginx作为主流反向代理服务器,其多级缓存架构(内存+磁盘+代理)可应对不同业务场景,20260225版本更实现了15%的命中率提升。通过合理配置proxy_cache_path指令和LRU淘汰机制,能有效管理缓存生命周期。典型应用包括静态资源加速、API响应缓存和大文件分片处理,配合Prometheus监控可构建完整的缓存性能指标体系。

cuibinmo3519的博客 397

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

构建高性能的ASP.NET应用(五)-如何开始寻找性能瓶颈

既然我们讲的是如何构建高性能的ASP.NET站点应用,那么我们就开始涉及网站方面的东西。我们说过,我们会把关注点放在“调优”上面。 在调优的时候,我们没有必要把事情搞的很复杂,要“由表及里。从整体到局部”。对于一个站点而言,我们最直接看到的就是网站的页面。换句话说,如果站点性能处理问题,肯定在页面上面会有反应。一个最显而易见的反应就是:页面加载很慢,半天看不到内容。 此时,我们可以...

weixin_34356555的博客 76

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

上一篇: 多线程环境下调用 HttpWebRequest 并发连接限制
下一篇: JQuery移除事件
ArvinStudy
博客等级 码龄15年 83粉丝 193原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值