96SEO 2026-02-19 10:41 11
巨巨巨巨长的提纲#xff0c;发车#xff01;发车#xff01;

头的格式标注颜色的表示与本文关联比较大的字段其他字段不做详细阐述。
包传给接收端主机每发送一次数据就「累加」一次该「数据字节数」的大小。
用来解决网络包乱序问题。
确认应答号指下一次「期望」收到的数据的序列号发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。
用来解决丢包的问题。
时表示希望建立连接并在其「序列号」的字段进行序列号初始值的设定。
时表示今后不会再有数据发送希望断开连接。
当通信结束希望断开连接时通信双方的主机之间就可以相互交换
层是「不可靠」的它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中的数据的完整性。
是一个工作在传输层的可靠数据传输的服务它能确保接收端接收的网络包是无损坏、无间隔、非冗余和按序的。
协议可以一个主机同时向多个主机发送消息也就是一对多是无法做到的
报文如果接收方的程序如果不知道「消息的边界」是无法读出一个有效的用户消息的。
并且
简单来说就是用于保证可靠性和流量控制维护的某些状态信息这些信息的组合包括
连接都要占用一定内存操作系统的内存是有限的如果内存资源被占满后会发生
协议发展的而当年可能并非如此依赖的可能是别的不提供自身报文长度或首部长度的网络层协议因此
地址来寻找网络中互连的主机或路由器。
在传输层中需要通过端口进行寻址来识别同一计算机中同时通信的不同应用程序。
所以传输层的「端口号」的作用是为了区分同一个主机上不同应用程序的数据包。
TCP/UDP所以可以根据这个信息确定送给哪个模块TCP/UDP处理送给
前必须先建立连接而建立连接是通过三次握手来进行的。
三次握手的过程如下图
报文发送给服务端表示向服务端发起连接该报文不包含应用层数据之后客户端处于
报文后首先服务端也随机初始化自己的序号server_isn将此序号填入
1。
最后把该报文发给客户端该报文也不包含应用层数据之后服务端处于
客户端收到服务端报文后还要向服务端回应最后一个应答报文首先该应答报文
最后把报文发送给服务端这次报文可以携带客户到服务端的数据之后客户端处于
从上面的过程可以发现第三次握手是可以携带数据的前两次握手是不可以携带数据的这也是面试常问的题。
相信大家比较常回答的是“因为三次握手才能保证双方具有接收和发送的能力。
”
简单来说三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。
报文还被网络阻塞了服务端并没有收到接着客户端重启后又重新向服务端建立连接发送了
使用三次握手建立连接的最主要原因就是防止「历史连接」初始化了连接。
我先直接说结论主要是因为在两次握手的情况下服务端没有中间状态给客户端来阻止历史连接导致服务端可能建立一个历史连接造成资源浪费。
状态假设这次是历史连接客户端判断到此次连接为历史连接那么就会回
状态所以它可以发送数据的但是它并不知道这个是历史连接它只有在收到
连接的场景下服务端在向客户端发送数据前并没有阻止掉历史连接导致服务端建立了一个历史连接又白白发送了数据妥妥地浪费了服务端的资源。
因此要解决这种现象最好就是在服务端发送数据前也就是建立连接之前要阻止掉历史连接这样就不会造成资源浪费而要实现这个功能就需要三次握手。
使用三次握手建立连接的最主要原因是防止「历史连接」初始化了连接。
状态收到了客户端发送的数据还是可以建立连接的并且还可以正常收到这个数据包。
这是因为数据报文中是有
所以服务端收到这个数据报文是可以正常建立连接的然后就可以正常接收这个数据包了。
连接中占据着非常重要的作用所以当客户端发送携带「初始序列号」的
报文已被服务端成功接收那当服务端发送「初始序列号」给客户端的时候依然也要得到客户端的应答回应这样一来一回才能确保双方的初始序列号能被可靠的同步。
四次握手其实也能够可靠的同步双方的初始化序号但由于第二步和第三步可以优化成一步所以就成了「三次握手」。
而两次握手只保证了一方的初始序列号能被对方成功接收没办法保证双方的初始序列号都能被确认接收。
报文那么服务端在收到请求后就会建立多个冗余的无效链接造成不必要的资源浪费。
我这里两次握手是假设「由于没有第三次握手服务端不清楚客户端是否收到了自己发送的建立连接的
建立连接时通过三次握手能防止历史连接的建立能减少双方不必要的资源开销能帮助双方同步初始化序列号。
序列号能够保证数据包不重复、不丢弃和按序传输。
「两次握手」无法防止历史连接的建立会造成双方资源的浪费也无法可靠的同步双方序列号
「四次握手」三次握手就已经理论上最少可靠连接建立所以不需要使用更多的通信次数。
连接在客户端发送数据包被网络阻塞了然后超时重传了这个数据包而此时服务端设备断电重启了之前与客户端建立的连接就消失了于是在收到客户端的数据包的时候就会发送
在新连接建立完成后上一个连接中被网络阻塞的数据包正好抵达了服务端刚好该数据包的序列号正好是在服务端的接收窗口内所以该数据包会被服务端正常接收就会造成数据错乱。
可以看到如果每次建立连接客户端和服务端的初始化序列号都是一样的话很容易出现历史报文被下一个相同四元组的连接接收的问题。
如果每次建立连接客户端和服务端的初始化序列号都「不一样」就有大概率因为历史报文的序列号「不在」对方接收窗口从而很大程度上避免了历史报文比如下图
相反如果每次建立连接客户端和服务端的初始化序列号都「一样」就有大概率遇到历史报文的序列号刚「好在」对方的接收窗口内从而导致历史报文被新连接成功接收。
所以每次初始化序列号不一样很大程度上能够避免历史报文被下一个相同四元组的连接接收注意是很大程度上并不是完全避免了因为序列号会有回绕的问题所以需要用时间戳的机制来判断历史报文
可以看到随机数是会基于时钟计时器递增的基本不可能会随机成一样的初始化序列号。
秒的这个超时时间是写死在内核里的如果想要更改则需要重新编译内核比较麻烦。
tcp_syn_retries内核参数控制这个参数是可以自定义的默认值一般是
/proc/sys/net/ipv4/tcp_syn_retries
报文是不会重传的所以如果服务端的第二次挥手丢失了客户端就会触发超时重传机制重传
函数关闭连接指定了只关闭发送方向而接收方向并没有关闭那么意味着主动关闭方还是可以接收数据的。
此时如果主动关闭方一直没收到第三次挥手那么主动关闭方的连接将会一直处于
倍如果还是没能收到客户端的第四次挥手ACK报文那么服务端就会断开连接。
Lifetime报文最大生存时间它是任何报文在网络上存在的最长时间超过这个时间报文将被丢弃。
因为
MSL比较合理的解释是网络中可能存在来自发送方的数据包当这些发送方的数据包被接收方处理后又会向对方发送响应所以一来一回需要等待
的时长呢你可以想象一个丢包率达到百分之一的糟糕网络连续两次丢包的概率只有万分之一这个概率实在是太小了忽略它比解决它更具性价比。
为了能更好的理解这个原因我们先来了解序列号SEQ和初始序列号ISN。
为每个传输方向上的每个字节都赋予了一个编号以便于传输成功后确认、丢失后重传以及在接收端保证不会乱序。
序列号是一个
建立连接的时候客户端和服务端都会各自生成一个初始序列号它是基于时钟生成的一个随机数来保证每个连接都拥有不同的初始序列号。
初始化序列号可被视为一个
就是序列号其中红色框住的分别是客户端和服务端各自生成的初始序列号。
通过前面我们知道序列号和初始化序列号并不是无限递增的会发生回绕为初始值的情况这意味着无法根据序列号来判断新老数据。
这时抵达了客户端而且该数据报文的序列号刚好在客户端接收窗口内因此客户端会正常接收这个数据报文但是这个数据报文是上一个连接残留下来的这样就产生数据错乱等严重的问题。
时长这个时间足以让两个方向上的数据包都被丢弃使得原来连接的数据包在网络中都自然消失再出现的数据包一定都是新建立连接所产生的。
为了防止这种情况出现客户端必须等待足够长的时间确保服务端能够收到
net.ipv4.ip_local_port_range参数指定范围。
PORT」都一样的服务端发起连接了但是被使用的端口还是可以继续对另外一个服务端发起连接的。
具体可以看我这篇文章客户端的端口可以重复使用吗(opens
状态连接过多的话就会受端口资源限制如果占满了所有端口资源那么就无法再跟「目的
不过即使是在这种场景下只要连接的是不同的服务端端口是可以重复使用的所以客户端还是可以向其他服务端发起连接的这是因为内核在定位一个连接的时候是通过四元组源IP、源端口、目的IP、目的端口信息来定位的并不会因为客户端的端口一样而导致连接冲突。
状态过多并不会导致端口资源受限因为服务端只监听一个端口而且由于一个四元组唯一确定一个
so_linger,sizeof(so_linger));如果l_onoff为非
但这为跨越TIME_WAIT状态提供了一个可能不过是一个非常危险的行为不值得提倡。
状态持续的时间是有一点长显得很不友好但是它被设计来就是用来避免发生乱七八糟的事情。
是我们的朋友它是有助于我们的不要试图避免这个状态而是应该弄清楚它。
状态的连接就永远不要主动断开连接让客户端去断开由分布在各处的客户端去承受
Keep-Alive然后当服务器收到请求作出回应的时候它也被添加到响应中
连接就不会中断而是保持连接。
当客户端发送另一个请求时它会使用同一个
都是默认打开的。
一旦客户端和服务端达成协议那么长连接就建立好了。
Keep-Alive都是由服务端主动关闭连接那么此时服务端上就会出现
可以往网络问题的方向排查比如是否是因为网络问题导致客户端发送的数据一直没有被服务端接收到以至于
长连接上最大能处理的请求数量当超过最大限制时就会主动关闭连接。
长连接上已经接收并处理的客户端请求的数量。
如果达到这个参数设置的最大值时则
状态是「被动关闭方」才会有的状态而且如果「被动关闭方」没有调用
epoll这样有新连接到来时服务端没办法感知这个事件也就无法获取到已连接的
socket导致当有大量的客户端主动断开了连接而服务端没机会对这些
状态的连接的时候通常都是代码的问题这时候我们需要针对具体的代码一步一步的进行排查和定位主要分析的方向就是服务端为什么没有调用
客户端出现故障指的是客户端的主机发生了宕机或者断电的场景。
发生这种情况的时候如果服务端一直不会发送数据给客户端那么服务端是永远无法感知到客户端宕机这个事件的也就是服务端的
保活机制会开始作用每隔一个时间间隔发送一个探测报文该探测报文包含的数据非常少如果连续几个探测报文都没有得到响应则认为当前的
内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔以下都为默认值
net.ipv4.tcp_keepalive_time7200
net.ipv4.tcp_keepalive_probes9tcp_keepalive_time7200表示保活时间是
保活的探测报文发送给对端后对端是可以响应的但由于没有该连接的有效信息会产生一个
第三种是对端主机宕机注意不是进程崩溃进程崩溃后操作系统在回收进程资源的时候会发送
保活机制来探测对方是不是发生了主机宕机或对端由于其他原因导致报文不可达。
当
保活的探测报文发送给对端后石沉大海没有响应连续几次达到保活探测次数后TCP
保活的这个机制检测的时间是有点长我们可以自己在应用层实现一个心跳机制。
秒内都没有再发起新的请求定时器的时间一到就会触发回调函数来释放该连接。
的连接信息是由内核维护的所以当服务端的进程崩溃后内核需要回收该进程的所有
报文后续的挥手过程也都是在内核完成并不需要进程的参与所以即使服务端的进程退出了还是能与客户端完成
阻塞调用返回这个时候服务端到客户端的单向连接也建立成功。
至此客户端与服务端两个方向的连接都建立成功。
会被放在已排队等候的其他已接收的数据之后这就意味着服务端需要处理这种异常情况因为
客户端是可以自己连自己的形成连接TCP自连接也可以两个客户端同时向对方发出请求建立连接TCP同时打开这两个情况都有个共同点就是没有服务端参与也就是没有
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback