IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

标签:TCP

共 72 篇相关文章

IT 累计浏览 36

百度网络监控工具开源第三弹:lidar — 不只是 pingmesh

百度开源的网络监控工具lidar是一种创新的探测方案,区别于传统pingmesh的全网互ping模式。传统pingmesh基于服务器间O(n²)复杂度的探测,百度原有netradar系统存在误报、漏报、时效慢和部署更新困难等问题。lidar采用单探测机发送TCP SYN包探测目标服务器,通过三种响应(SYN-ACK、RST、无响应)直接判断网络状态,无需安装agent或服务器端配置,简化了运维。开发中解决了跨平台收包差异:Linux上使用raw socket接收TCP响应副本,而macOS由于内核拦截,需通过BPF设备在链路层抓包。为优化高吞吐服务器性能,使用BPF过滤器在内核层过滤无关报文,仅投递匹配探测端口的报文,减少用户态开销。通过源端口轮转策略覆盖ECMP多路径,提高探测全面性。lidar具有高时效、高准确率和易于更新的优点,适用于机房内外网络监控,支持多种配置和高速率探测,已开源供社区使用。

IT 累计浏览 2,576

Golang socket 里面奇怪的 pipe 使用

这篇讲的是一个Go语言代理服务器在排查文件描述符时遇到的蹊跷事。 作者日常监控发现,一个TCP连接数两万多的服务,在系统的`/proc/pid/fd`目录下却有五万多个pipe文件描述符,数量远超socket本身。这不符合直觉,于是开始深挖源码。 根因最终指向了Go在Linux下对`net.Conn.readFrom`方法的优化。为了减少用户态内存拷贝,Go会尝试使用`splice`系统调用在内核态直接完成数据传输。而`splice`要求一方必须是管道,因此其实现略显“绕”:每次`readFrom`操作都会先通过`pipe2`创建一对临时管道,再分别进行`splice`操作,用完即关。这完美解释了那些额外pipe的来源。 作者也指出,尽管这种“管道中转”的实现看起来不甚优雅,但在像代理这样`readFrom`生命周期较长的场景中,其性能收益依然可观,因此通常无需优化。文章通过一次具体的生产现象,清晰揭示了Go网络库中一个精巧但隐蔽的内核级优化机制。

IT 累计浏览 2,103

TCP 滑动窗口 与窗口缩放因子(Window Scaling)

这篇讲的是TCP滑动窗口协议中一个常被忽略但影响重大的参数:窗口缩放因子(Window Scaling)。文章指出,TCP窗口字段本身只有16位,最大值为65535字节。在“高带宽-长延迟”的网络中,这个上限会成为性能瓶颈——比如在10Mbps、单向延迟80ms的链路上,理想窗口需要约100KB,但65KB的窗口迫使发送方必须等待确认,白白浪费了带宽。 为了解决这个问题,窗口缩放选项被引入。它通过在TCP握手中协商一个“缩放因子”,将接收到的窗口值左移该因子位,从而将最大窗口理论上扩展至约1GB(缩放因子最大为14)。文章通过计算示例说明,原先65KB的窗口经过缩放后,能够匹配高带宽网络的实际吞吐需求。 作者在实战中也验证了其效果:对一个上传服务进行调优,增大TCP缓冲区并启用窗口缩放后,上传一个8MB视频文件的时间从1分30秒显著缩短至20秒,体现了在特定网络环境下对此参数进行调优的实际价值。

IT 累计浏览 2,631

Windows 下重定向当前进程的 stdout 到网络连接

这篇讲的是在 Windows 系统下,如何将一个正在运行的进程的标准输出(stdout)重定向到一个 TCP 网络连接中。这并非一个简单的 API 调用,作者为了解决这个需求,深入探索了 Windows 与 POSIX 在底层 I/O 机制上的根本差异。 作者指出,尽管 Windows 提供了 `_dup2` 来模拟 POSIX 的 `dup2`,但其进程标准输出句柄(HANDLE)与 C 运行时的文件描述符(fd)之间的绑定关系是静态的。在进程运行时调用 `SetStdHandle` 并无法影响 `cout` 或 `printf` 的输出流,这是解决问题的第一个关键障碍。 更麻烦的是,Windows 下的 socket 不能直接作为普通的文件句柄使用,因此无法通过 `dup2` 直接传递。作者最终采用的核心方案是:先用 `dup2` 将 stdout 重定向到一个匿名管道,然后启动一个独立的转发线程,持续从该管道读取数据并发送到目标网络连接中。这个方案还巧妙地解决了进程结束时可能丢失末尾输出的问题——通过主动关闭管道来通知转发线程结束,确保数据完整性。 整个探索过程涉及了 Windows 内核对象、句柄复制、管道 I/O 与多线程同步等多个层面的考量,最终作者将实现封装成了一个 Lua 模块,并在 GitHub 上提供了可运行的示例代码。

IT 累计浏览 3,237

关于TCP可靠性的一点思考,借此浅谈应用层协议设计

这篇讲的是,作者从网络游戏开发转向网络存储、机器学习等场景后,对TCP“可靠性”的重新审视。他提出,在需要重连重试的严肃应用中,TCP的ACK机制和操作系统的发送成功通知并不可靠——比如网络故障后,应用层无法获知哪些数据丢失,已提交的缓冲区也可能被释放,导致数据无法重发。 文章的核心,是剖析了三个基于TCP的应用层协议设计陷阱:发送方无法确认接收状态、无法区分“成功”与“未失败”、以及重试可能导致数据重复。针对这些“坑”,作者给出了具体的应对方案:必须在应用层设计确认应答(ACK);对于大文件追加,应采用带偏移量的positioned write;对于重复消息,则需在应用层进行去重。 最后,文章也讨论了优雅关闭连接的原则:应由接收最后一条消息的一方主动发起关闭。整篇文章从实际场景中的问题切入,深入浅出地阐明了在设计RPC协议时,不能盲目信任传输层,而必须在应用层构建自己的可靠性机制。

IT 累计浏览 4,158

可靠 UDP 传输

这篇关于可靠 UDP 传输的文章,作者从对 TCP over UDP 的审慎态度出发,深入探讨了其可能的应用场景与实现路径。 作者首先指出,强行在 UDP 上复制一个完整可靠的传输协议往往得不偿失。其优势通常只在特定条件下显现,例如游戏状态同步等对包序不敏感、或采用一问一答请求模式的场景——这类小数据量交互正是 TCP 建立/拆除连接开销的短板所在。 核心方案上,作者认为一个可行的“可靠 UDP”模块,应专注于解决“如何利用不可靠传输实现可靠协议”这一逻辑问题,而非直接绑定 UDP 收发。他提出的 API 设计,将可靠化逻辑封装为独立层,业务层仅需调用发送与接收接口,而由底层的 `rudp_update` 函数处理数据包组序、重传请求与心跳维持。 作者分享了一个轻量级的 C 语言实现(约 500 行),采用了请求重发机制、16bit 包序号、以及可配置的发送延迟与超时策略。他强调,其实用性在于简化逻辑,并通过超时而非复杂确认来清理过期数据,为特定低延迟需求提供了一个灵活且易于修改的参考起点。

IT 累计浏览 2,677

nc 传送文件

这篇讲的是如何用nc(netcat)这个网络工具直接传输文件,省去了传统方法中压缩、解压或配置权限的麻烦。作者从一个非常实用的角度切入,直接给出了传送整个文件夹和单个文件的具体命令行操作。 文章核心在于展示nc配合管道和tar命令的简洁性。传送文件夹时,发送端通过tar打包压缩后管道给nc,接收端则监听端口并用tar解压还原,整个过程一步到位。对于单个文件,方法更为直接,用cat或重定向即可完成内容流式传输。这种用法尤其适合内网环境下快速交换配置文件或日志。 作者没有展开复杂原理,而是聚焦于命令的实际写法和效果。通过这两组清晰的命令示例,读者能立刻上手操作,体会到这种轻量级方案在运维和开发场景中的便利性。

IT 累计浏览 2,205

TCP相关参数解释

这篇系统梳理了Linux内核中影响TCP连接行为的关键网络参数。它围绕连接建立、保活检测、超时重试和状态回收等环节,逐一解释了如`tcp_syn_retries`、`tcp_keepalive_time`、`tcp_fin_timeout`等参数的含义、默认值及其对网络超时计算的影响。 文章不仅停留在定义层面,更结合了实际的调优场景。例如,它指出在高负载Web服务器或NAT环境下,许多默认值(如`tcp_retries2`的15次重试、`tcp_fin_timeout`的60秒)往往偏于保守,可能导致资源被空闲连接长期占用。作者分享了在不同环境下的调整经验,如将`tcp_syn_retries`降至2以加快连接放弃速度,或将`tcp_keepalive_intvl`缩短至15秒来更快地发现断开连接。 特别值得注意的是,文章对`tcp_syncookies`、`tcp_tw_recycle`这类涉及安全或特定场景(如NAT)的开关选项给出了明确的使用建议与风险提示,强调了参数调整需结合实际攻击面与服务类型。整体上,这是一份将内核参数文档与实战调优经验相结合的参考指南,帮助读者理解参数背后的网络原理,并为优化服务器性能提供具体思路。

IT 累计浏览 7,016

TCP 的那些事儿(下)

这篇讲的是TCP协议核心机制中的“动态调整”与“流控”部分,聚焦于RTT算法演进和滑动窗口原理。作者从一个实际问题切入:重传超时时间(RTO)为何不能固定设置?由此引出RTT(网络往返时长)的测量难题。 文章清晰对比了三代算法。经典算法依赖加权平均,但容易掩盖网络抖动;Karn算法为解决重传采样矛盾选择“忽略重传”,却又用粗暴的“超时翻倍”来应对网络突变;最终,Linux内核采用的Jacobson/Karels算法则更胜一筹,它引入“偏差”因子,能敏锐感知RTT的波动,计算出更精准的RTO。 另一重点是滑动窗口。文章用生动图示拆解了接收端如何通过Advertised-Window告诉发送端“我能收多少”,从而实现流量控制,并详细说明了Zero Window的处理机制及潜在的DDoS风险。整篇内容扎实,用“不适合在厕所中阅读”幽默地暗示了其思维深度,将抽象算法与网络稳定性的现实关联讲得透彻明白。

IT 累计浏览 22,695

TCP 的那些事儿(上)

这篇讲的是TCP协议的核心机制,作者从一个经典却复杂的网络协议出发,试图用清晰的方式梳理其设计原理。文章开篇就点明了学习TCP的挑战,并直接切入重点:TCP头格式。它解释了序号、确认号、窗口和标志位这四个关键字段如何分别解决网络包乱序、丢包、流控和状态控制这些实际问题。 接着,文章用两张图——TCP状态机与建连/断连流程——对照着讲解,把三次握手为何必要、四次挥手的本质说透了。它特别分析了ISN序列号初始化如何避免旧包干扰,以及TIME_WAIT状态存在的双重意义。更有价值的是,作者深入到了实战细节:比如Linux下SYN超时的重试策略(默认63秒),并警示了SYN Flood攻击的原理与tcp_syncookies的应对方式及其局限性。 这不是一篇面面俱到的协议手册,而是聚焦于TCP最根本的“连接”幻觉与可靠传输的实现,通过状态机和具体参数(如MSL、tcp_max_syn_backlog)的剖析,展现了这个30多年协议在精巧设计与现实妥协之间的平衡。读下来,能对那些看似理所当然的网络行为,建立起更扎实的认知。

IT 累计浏览 1,824

为什么 skynet 提供的包协议只用 2 个字节表示包长度

这篇讲的是 skynet 框架中一个经典设计决策:为什么它的 netpack 库坚持使用 2 字节(最大 64KB)来表示 TCP 数据包长度,而不是更“灵活”的 4 字节。 作者从游戏客户端网络通信的实际场景出发,解释了这并非简单的技术限制,而是一种有意的引导。核心原因在于,在单个 TCP 连接中允许过大的数据包(比如 100KB)是一个糟糕的设计。这会在弱网环境下长时间阻塞整个通信信道,连带心跳包等需要及时响应的小数据包也被延迟,严重影响实时性。更进一步,4 字节的长度头还存在被恶意攻击耗尽服务器内存的安全风险。 因此,作者主张正确的做法不是放宽包长度限制,而是在“长度+内容”协议之上增加一层,将大数据块分片传输。这个设计看似“绕”,但它强制开发者去思考和解决数据传输的阻塞问题,最终能实现单个 TCP 连接承载多个逻辑信道的能力,比如区分高优先级的心跳/关键指令和低优先级的聊天信息或大文件分片。 所以,skynet 这个看似限制性的选择,其实是在用简洁的接口引导使用者构建更健壮、响应更及时的网络架构。

IT 累计浏览 4,709

关于FIN_WAIT1

这篇讲的是TCP连接关闭过程中FIN_WAIT1状态持续时间的问题。作者从TCPCopy社区的一个讨论切入,先通过经典的四次挥手流程图帮我们回忆TCP关闭的步骤,重点解释了主动关闭方在发出FIN包后所处的FIN_WAIT1状态。 文章核心是纠正一个常见误解:很多资料会说tcp_fin_timeout控制FIN_WAIT1的超时,但实际上这个参数控制的是FIN_WAIT2状态的持续时间。真正的关键参数是tcp_orphan_retries,它决定了当FIN包的ACK确认未收到时,系统会进行多少次重试。作者通过一个用netcat和iptables搭建的实验,清晰地展示了FIN包被丢弃后的重试行为——每次重试间隔翻倍(约200ms,400ms,800ms...),并引用了Linux内核源码来证明当tcp_orphan_retries设为0时实际生效值为8。 因此,对于线上出现大量FIN_WAIT1连接的服务器,解决方案很明确:根据网络状况适当调低tcp_orphan_retries的值。文章最后还延伸了一点,讨论了FIN_WAIT1状态可能被利用进行DoS攻击的风险,使话题更深入。

IT 累计浏览 4,195

构建C1000K的服务器(1) – 基础

当C10K问题已成为历史,作者将目光投向了更宏大的C1000K挑战。对于Twitter、微博这类需要维持千万级实时连接的平台,单机百万连接(C1000K)的能力能极大降低服务器集群规模。 这篇文章并没有直接给出某个框架或库的解决方案,而是从根源出发,剖析了限制C1000K实现的四大核心因素。作者以Linux为例,深入讲解了如何突破操作系统默认的“最大打开文件数”限制,给出了包括临时修改(ulimit)和永久配置(sysctl.conf, limits.conf)在内的具体方法与命令。文章还通过一个原始的C语言服务器程序,实际测量并验证了操作系统为维护百万连接所消耗的内存,将理论估算与实际开销结合起来分析。 作者强调,解决C1000K问题不能盲目追求新技术,而应先理清操作系统内核、内存分配与网络吞吐这些底层瓶颈。文中的系统参数配置和测试思路,为需要应对海量并发连接的开发者提供了切实可行的排查起点和优化依据。

IT 累计浏览 2,299

实用命令行工具详解(四)—netcat

这篇讲的是Linux下的网络调试利器netcat(简称nc),它被称作“网络工具中的瑞士军刀”,能通过TCP和UDP在网络中读写数据。文章具体拆解了它的三个实用场景:建立监听端口进行基础通信、利用管道实现文件快速传输,以及通过-w参数设置连接超时以控制会话时长。每个场景都提供了清晰的客户端与服务器端命令示例,比如用`cat local | nc localhost 9999`来推送文件内容,或用`nc -w 10`来自动中断空闲连接。这些例子展示了如何将netcat与重定向、管道结合,在脚本或临时调试中灵活使用。

IT 累计浏览 4,022

手机应用/服务器开发的一些总结(二)

这篇讲的是自定义TCP socket开发中的实践经验与方案对比。作者从Android客户端和服务器端两个维度展开,重点讨论了阻塞与非阻塞socket的选型及具体实现中的“坑”。 Android端部分,作者对比了传统阻塞socket与NIO的使用差异,特别分享了NIO在实际业务中遇到的问题。例如网络断线时`finishConnect()`可能长时间阻塞,解决方案是通过`setSoTimeout`设置合理超时。同时也指出了NIO下`channel.read`不同返回值(如-1表示关闭、0表示无数据)的准确含义,这些细节对稳定开发至关重要。 Server端部分,作者分析了从Python标准库`ThreadingTCPServer`到异步框架tornado与gevent的演进。他指出,tornado的异步IO虽然性能高,但业务代码不能阻塞,使用起来有一定痛苦;而gevent则兼顾了性能与编码便利性。基于此,作者还封装了`tkola`和`gkola`两个库,采用类似Flask的装饰器风格来简化TCP server开发,并提供了清晰的代码示例。 总的来说,文章不仅梳理了不同场景下的技术选型逻辑,更分享了生产环境中的具体解决方案与开源工具,对从事移动端与服务器网络编程的开发者有较强的实用参考价值。

IT 累计浏览 4,465

再叙TIME_WAIT

这篇文章从一次“被反复问到”的经历出发,全面梳理了 TCP 协议中的 TIME_WAIT 状态。作者首先用几条简单的 Linux 命令,带我们直观感受繁忙服务器上动辄数万的 TIME_WAIT 连接。文章的核心在于解释了这种状态存在的“必要性”:它通过等待两倍的报文最大生存时间(MSL),确保双向关闭握手的数据包不会在不可靠的网络上引发混乱或干扰新连接。 接着,文章深入对比了控制 TIME_WAIT 数量的几种主流内核参数调优方案。其中,`ip_conntrack` 虽能调整超时,但作者指出它带来的性能下降可能得不偿失。而广为流传的 `tcp_tw_recycle` 参数则隐藏着一个在 NAT 环境下可能导致连接失败的“时间戳陷阱”。相比之下,`tcp_tw_reuse` 被认为相对安全,但其关键限制在于仅对连接发起方(如作为客户端的 PHP)有效,且依赖时间戳递增机制。 整体来看,这篇文章不是在简单罗列解决方案,而是深入剖析了问题的成因与各种方案的权衡。它提醒我们,那些试图强行缩短 TIME_WAIT 的“快捷方式”往往伴随风险,而理解其设计原理,才能为一次连接的优雅退场赋予合理的等待时间。

IT 累计浏览 1,634

监控Netstat中的TCP数据

作者从实际运维中遇到的netstat报错说起:当执行netstat命令时,若版本较旧可能触发“error parsing /proc/net/netstat”错误。解决方法是通过rpm确认netstat属于net-tools包,随后用yum升级即可修复。不过,文章的重点不止于故障排查,更延伸到如何有效监控TCP连接数据。 作者指出,直接监控netstat -s输出的绝对值(如连接数、段收发量)在Graphite等工具中几乎是一条平直线——因为数值基数太大,微小波动肉眼无法识别。真正有价值的是捕捉这些数据的相对变化率。为此,他分享了一段可直接运行的Shell脚本,通过循环对比相邻时刻的TCP统计值,实时输出增量数据,让监控图表清晰反映系统的动态趋势。 这篇文章从一个具体错误入手,最终给出了提升监控有效性的实用技巧,对需要关注TCP连接状态的运维人员颇具参考价值。

IT 累计浏览 15,932

从输入 URL 到页面加载完成的过程中都发生了什么事情?

这篇文章详细拆解了“输入URL到页面加载”这个经典问题的前两个环节,其独特之处在于从最底层的硬件交互开始讲起,串联起了整个技术栈。 作者从用户触摸屏幕的那一刻说起,解释了电容触摸屏如何将物理动作转换为电信号,通过I²C总线传递给CPU。在CPU内部,信号经过晶体管和逻辑门电路,最终触发操作系统的中断机制。以Android为例,内核驱动将触摸事件写入设备文件,再由系统的GUI框架(如EventHub)分发给前台应用,也就是浏览器。 当事件到达浏览器后,文章揭示了其中一些不为人知的优化。例如,Chrome会根据用户输入历史进行“预预测”,在按下回车键之前就可能开始建立网络连接或渲染,以加速页面显示。文章后续部分显然还会继续剖析网络请求、DNS解析等后续流程。 这篇长文并非只为面试准备,而是旨在建立硬件、操作系统与软件之间的关联认知。作者在文中推荐了从《编码》到《Linux内核设计与实现》等多本经典著作,适合希望深入理解计算系统工作原理的读者。

IT 累计浏览 6,421

计算机网络协议赏析-HTTP

大家每天都在敲击的http://,可能是计算机网络里最“熟悉的陌生人”。这篇文章从这个视角切入,带我们重新认识这位应用层的明星协议。 它将HTTP与幕后的TCP/IP协议对比,点明HTTP作为用户直接面对的“台前大腕”的地位。作者没有停留在概念层面,而是清晰地拆解了HTTP工作的四个步骤:从TCP连接建立,到客户端发出请求报文,服务器返回响应报文,最后连接断开。 文章的核心价值在于将协议细节“可视化”。它详细展示了一次典型的HTTP请求和响应报文长什么样,并解释了每一行代码的作用——从请求方法、头部字段,到那个容易被忽略但至关重要的空行。同时,文章也系统梳理了那些常见的状态码:从200 OK到404 Not Found,再到500服务器错误,让读者真正读懂这些数字背后的含义。 除了基础,文章还延伸到了HTTP 1.0与1.1版本的演进,特别是“持久连接”这一关键改进,并提及了缓存控制等高级用法。整篇文章像一位耐心的向导,将抽象的协议规范转化为具体可感的报文结构,帮助读者建立起对HTTP工作原理的扎实理解。

IT 累计浏览 2,905

底层通讯协议问题排查案例

这篇讲的是作者在处理用户技术支持时,亲历的一系列底层网络通讯协议“踩坑”与排查实录。这些案例看似离奇,根因却往往藏在协议栈的深处或网络环境的微妙配置中。 文章详细拆解了五个典型案例:包括NAT环境下TCP时间戳机制导致的连接失败、ISP篡改MTU引发的UDP丢包、中间网络设备异常引起的MSS分片问题、TCP动态窗口无法增长导致的速率极低,以及网卡速率协商错误造成的单向慢传输。每个案例都从具体现象出发,通过抓包分析等手段定位到根本原因,并给出了如调整内核参数(tcp_timestamps、tcp_window_scaling)、修改MSS值、检查网卡状态等明确的解决方法。 这不仅是一份实用的故障排查手册,更像是一份网络协议在复杂生产环境中行为特性的观察笔记。作者将枯燥的协议规范(如RFC1323、MTU)与鲜活的一线问题结合,展示了如何从表象层层深挖至协议与环境的交互点。对于需要处理类似网络疑难杂症的开发者或运维人员,文中从现象推导到根因的排查思路,以及那些意想不到的解决方案,都提供了直接的参考和启发。