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

沾益县住房和城乡建设局网站电子商务网站建设侧重哪几个方面

沾益县住房和城乡建设局网站,电子商务网站建设侧重哪几个方面,网站建设收费标准精英,西安旅游服务网站建设哈喽#xff1a;亲爱的小伙伴#xff0c;首先祝大家五一快乐~本来打算节日 happy 一下就不发文了#xff0c;但想到有些小伙伴可能因为疫情的原因没出去玩#xff0c;或者劳逸结合偶尔刷刷公众号#xff0c;所以今天就诈尸更新一篇干货#xff0c;给大家解解闷~前言不管面… 哈喽亲爱的小伙伴首先祝大家五一快乐~本来打算节日 happy 一下就不发文了但想到有些小伙伴可能因为疫情的原因没出去玩或者劳逸结合偶尔刷刷公众号所以今天就诈尸更新一篇干货给大家解解闷~前言不管面试 Java 、C/C、Python 等开发岗位 TCP 的知识点可以说是的必问的了。任 TCP 虐我千百遍我仍待 TCP 如初恋。遥想小林当年校招时常因 TCP 面试题被刷真是又爱又狠….过去不会没关系今天就让我们来消除这份恐惧微笑着勇敢的面对它吧所以小林整理了关于 TCP 三次握手和四次挥手的面试题型跟大家一起探讨探讨。TCP 基本认识TCP 连接建立TCP 连接断开Socket 编程PS本次文章不涉及 TCP 流量控制、拥塞控制、可靠性传输等方面知识这些留在下篇哈正文01 TCP 基本认识瞧瞧 TCP 头格式我们先来看看 TCP 头的格式标注颜色的表示与本文关联比较大的字段其他字段不做详细阐述。TCP 头格式序列号在建立连接时由计算机生成的随机数作为其初始值通过 SYN 包传给接收端主机每发送一次数据就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。确认应答号指下一次「期望」收到的数据的序列号发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决不丢包的问题。控制位ACK该位为 1 时「确认应答」的字段变为有效TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1 。RST该位为 1 时表示 TCP 连接中出现异常必须强制断开连接。SYC该位为 1 时表示希望建立连并在其「序列号」的字段进行序列号初始值的设定。FIN该位为 1 时表示今后不会再有数据发送希望断开连接。当通信结束希望断开连接时通信双方的主机之间就可以相互交换 FIN 位置为 1 的 TCP 段。为什么需要 TCP 协议TCP 工作在哪一层IP 层是「不可靠」的它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中的数据的完整性。OSI 参考模型与 TCP/IP 的关系如果需要保障网络数据包的可靠性那么就需要由上层传输层的 TCP 协议来负责。因为 TCP 是一个工作在传输层的可靠数据传输的服务它能确保接收端接收的网络包是无损坏、无间隔、非冗余和按序的。什么是 TCP TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。面向连接一定是「一对一」才能连接不能像 UDP 协议 可以一个主机同时向多个主机发送消息也就是一对多是无法做到的可靠的无论的网络链路中出现了怎样的链路变化TCP 都可以保证一个报文一定能够到达接收端字节流消息是「没有边界」的所以无论我们消息有多大都可以进行传输。并且消息是「有序的」当「前一个」消息没有收到的时候即使它先收到了后面的字节已经收到那么也不能扔给应用层去处理同时对「重复」的报文会自动丢弃。什么是 TCP 连接我们来看看 RFC 793 是如何定义「连接」的Connections: The reliability and flow control mechanisms described above require that TCPs initialize and maintain certain status information for each data stream.  The combination of this information, including sockets, sequence numbers, and window sizes, is called a connection.简单来说就是用于保证可靠性和流量控制维护的某些状态信息这些信息的组合包括Socket、序列号和窗口大小称为连接。所以我们可以知道建立一个 TCP 连接是需要客户端与服务器端达成上述三个信息的共识。Socket由 IP 地址和端口号组成序列号用来解决乱序问题等窗口大小用来做流量控制如何唯一确定一个 TCP 连接呢TCP 四元组可以唯一的确定一个连接四元组包括如下源地址源端口目的地址目的端口TCP 四元组源地址和目的地址的字段32位是在 IP 头部中作用是通过 IP 协议发送报文给对方主机。源端口和目的端口的字段16位是在 TCP 头部中作用是告诉 TCP 协议应该把报文发给哪个进程。有一个 IP 的服务器监听了一个端口它的 TCP 的最大连接数是多少服务器通常固定在某个本地端口上监听等待客户端的连接请求。因此客户端 IP 和 端口是可变的其理论值计算公式如下:对 IPv4客户端的 IP 数最多为 2 的 32 次方客户端的端口数最多为 2 的 16 次方也就是服务端单机最大 TCP 连接数约为 2 的 48 次方。当然服务端最大并发 TCP 连接数远不能达到理论上限。首先主要是文件描述符限制Socket 都是文件所以首先要通过 ulimit 配置文件描述符的数目另一个是内存限制每个 TCP 连接都要占用一定内存操作系统是有限的。UDP 和 TCP 有什么区别呢分别的应用场景是UDP 不提供复杂的控制机制利用 IP 提供面向「无连接」的通信服务。UDP 协议真的非常简头部只有 8 个字节 64 位UDP 的头部格式如下UDP 头部格式目标和源端口主要是告诉 UDP 协议应该把报文发给哪个进程。包长度该字段保存了 UDP 首部的长度跟数据的长度之和。校验和校验和是为了提供可靠的 UDP 首部和数据而设计。TCP 和 UDP 区别1. 连接TCP 是面向连接的传输层协议传输数据前先要建立连接。UDP 是不需要连接即刻传输数据。2. 服务对象TCP 是一对一的两点服务即一条连接只有两个端点。UDP 支持一对一、一对多、多对多的交互通信3. 可靠性TCP 是可靠交付数据的数据可以无差错、不丢失、不重复、按需到达。UDP 是尽最大努力交付不保证可靠交付数据。4. 拥塞控制、流量控制TCP 有拥塞控制和流量控制机制保证数据传输的安全性。UDP 则没有即使网络非常拥堵了也不会影响 UDP 的发送速率。5. 首部开销TCP 首部长度较长会有一定的开销首部在没有使用「选项」字段时是 20 个字节如果使用了「选项」字段则会变长的。UDP 首部只有 8 个字节并且是固定不变的开销较小。TCP 和 UDP 应用场景由于 TCP 是面向连接能保证数据的可靠性交付因此经常用于FTP 文件传输HTTP / HTTPS由于 UDP 面向无连接它可以随时发送数据再加上UDP本身的处理既简单又高效因此经常用于包总量较少的通信如 DNS 、SNMP 等视频、音频等多媒体通信广播通信为什么 UDP 头部没有「首部长度」字段而 TCP 头部有「首部长度」字段呢原因是 TCP 有可变长的「选项」字段而 UDP 头部长度则是不会变化的无需多一个字段去记录 UDP 的首部长度。为什么 UDP 头部有「包长度」字段而 TCP 头部则没有「包长度」字段呢先说说 TCP 是如何计算负载数据长度其中 IP 总长度 和 IP 首部长度在 IP 首部格式是已知的。TCP 首部长度则是在 TCP 首部格式已知的所以就可以求得 TCP 数据的长度。大家这时就奇怪了问“ UDP 也是基于 IP 层的呀那 UDP 的数据长度也可以通过这个公式计算呀为何还要有「包长度」呢”这么一问确实感觉 UDP 「包长度」是冗余的。因为为了网络设备硬件设计和处理方便首部长度需要是 4字节的整数倍。如果去掉 UDP 「包长度」字段那 UDP 首部长度就不是 4 字节的整数倍了所以小林觉得这可能是为了补全 UDP 首部长度是 4 字节的整数倍才补充了「包长度」字段。02 TCP 连接建立TCP 三次握手过程和状态变迁TCP 是面向连接的协议所以使用 TCP 前必须先建立连接而建立连接是通过三次握手而进行的。TCP 三次握手一开始客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口处于 LISTEN 状态第一个报文—— SYN 报文客户端会随机初始化序号client_isn将此序号置于 TCP 首部的「序号」字段中同时把 SYN 标志位置为 1 表示 SYN 报文。接着把第一个 SYN 报文发送给服务端表示向服务端发起连接该报文不包含应用层数据之后客户端处于 SYN-SENT 状态。第二个报文 —— SYN ACK 报文服务端收到客户端的 SYN 报文后首先服务端也随机初始化自己的序号server_isn将此序号填入 TCP 首部的「序号」字段中其次把 TCP 首部的「确认应答号」字段填入 client_isn 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端该报文也不包含应用层数据之后服务端处于 SYN-RCVD 状态。第三个报文 —— ACK 报文客户端收到服务端报文后还要向服务端回应最后一个应答报文首先该应答报文 TCP 首部 ACK 标志位置为 1 其次「确认应答号」字段填入 server_isn 1 最后把报文发送给服务端这次报文可以携带客户到服务器的数据之后客户端处于 ESTABLISHED 状态。服务器收到客户端的应答报文后也进入 ESTABLISHED 状态。从上面的过程可以发现第三次握手是可以携带数据的前两次握手是不可以携带数据的这也是面试常问的题。一旦完成三次握手双方都处于 ESTABLISHED 状态此致连接就已建立完成客户端和服务端就可以相互发送数据了。如何在 Linux 系统中查看 TCP 状态TCP 的连接状态查看在 Linux 可以通过 netstat -napt 命令查看。TCP 连接状态查看为什么是三次握手不是两次、四次相信大家比较常回答的是“因为三次握手才能保证双方具有接收和发送的能力。”这回答是没问题但这回答是片面的并没有说出主要的原因。在前面我们知道了什么是 TCP 连接用于保证可靠性和流量控制维护的某些状态信息这些信息的组合包括Socket、序列号和窗口大小称为连接。所以重要的是为什么三次握手才可以初始化Socket、序列号和窗口大小并建立 TCP 连接。接下来以三个方面分析三次握手的原因三次握手才可以阻止历史重复连接的初始化主要原因三次握手才可以同步双方的初始序列号三次握手才可以避免资源浪费原因一避免历史连接我们来看看 RFC 793 指出的 TCP 连接使用三次握手的首要原因The principle reason for the three-way handshake is to prevent old duplicate connection initiations from causing confusion.简单来说三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。网络环境是错综复杂的往往并不是如我们期望的一样先发送的数据包就先到达目标主机反而它很骚可能会由于网络拥堵等乱七八糟的原因会使得旧的数据包先到达目标主机那么这种情况下 TCP 三次握手是如何避免的呢三次握手避免历史连接客户端连续发送多次 SYN 建立连接的报文在网络拥堵等情况下一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端那么此时服务端就会回一个 SYN ACK 报文给客户端客户端收到后可以根据自身的上下文判断这是一个历史连接序列号过期或超时那么客户端就会发送 RST 报文给服务端表示中止这一次连接。如果是两次握手连接就不能判断当前连接是否是历史连接三次握手则可以在客户端发送方准备发送第三次报文时客户端因有足够的上下文来判断当前连接是否是历史连接如果是历史连接序列号过期或超时则第三次握手发送的报文是 RST 报文以此中止历史连接如果不是历史连接则第三次发送的报文是 ACK 报文通信双方就会成功建立连接所以 TCP 使用三次握手建立连接的最主要原因是防止历史连接初始化了连接。原因二同步双方初始序列号TCP 协议的通信双方 都必须维护一个「序列号」 序列号是可靠传输的一个关键因素它的作用接收方可以去除重复的数据接收方可以根据数据包的序列号按序接收可以标识发送出去的数据包中 哪些是已经被对方收到的可见序列号在 TCP 连接中占据着非常重要的作用所以当客户端发送携带「初始序列号」的 SYN 报文的时候需要服务端回一个 ACK 应答报文表示客户端的 SYN 报文已被服务端成功接收那当服务端发送「初始序列号」给客户端的时候依然也要得到客户端的应答回应这样一来一回才能确保双方的初始序列号能被可靠的同步。四次握手与三次握手四次握手其实也能够可靠的同步双方的初始化序号但由于第二步和第三步可以优化成一步所以就成了「三次握手」。而两次握手只保证了一方的初始序列号能被对方成功接收没办法保证双方的初始序列号都能被确认接收。原因三避免资源浪费如果只有「两次握手」当客户端的 SYN 请求连接在网络中阻塞客户端没有接收到 ACK 报文就会重新发送 SYN 由于没有第三次握手服务器不清楚客户端是否收到了自己发送的建立连接的 ACK 确认信号所以每收到一个 SYN 就只能先主动建立一个连接这会造成什么情况呢如果客户端的 SYN 阻塞了重复发送多次 SYN 报文那么服务器在收到请求后就会建立多个冗余的无效链接造成不必要的资源浪费。两次握手会造成资源浪费即两次握手会造成消息滞留情况下服务器重复接受无用的连接请求 SYN 报文而造成重复分配资源。小结TCP 建立连接时通过三次握手能防止历史连接的建立能减少双方不必要的资源开销能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。不使用「两次握手」和「四次握手」的原因「两次握手」无法防止历史连接的建立会造成双方资源的浪费也无法可靠的同步双方序列号「四次握手」三次握手就已经理论上最少可靠连接建立所以不需要使用更多的通信次数。为什么客户端和服务端的初始序列号 ISN 是不相同的因为网络中的报文会延迟、会复制重发、也有可能丢失这样会造成的不同连接之间产生互相影响所以为了避免互相影响客户端和服务端的初始序列号是随机且不同的。初始序列号 ISN 是如何随机产生的起始 ISN 是基于时钟的每 4 毫秒 1转一圈要 4.55 个小时。RFC1948 中提出了一个较好的初始化序列号 ISN 随机生成算法。ISN M F (localhost, localport, remotehost, remoteport)M 是一个计时器这个计时器每隔 4 毫秒加 1。F 是一个 Hash 算法根据源 IP、目的 IP、源端口、目的端口生成一个随机数值。要保证 Hash 算法不能被外部轻易推算得出用 MD5 算法是一个比较好的选择。既然 IP 层会分片为什么 TCP 层还需要 MSS 呢我们先来认识下 MTU 和 MSSMTU 与 MSSMTU一个网络包的最大长度以太网中一般为 1500 字节MSS除去 IP 和 TCP 头部之后一个网络包所能容纳的 TCP 数据的最大长度如果TCP 的整个报文头部 数据交给 IP 层进行分片会有什么异常呢当 IP 层有一个超过 MTU 大小的数据TCP 头部 TCP 数据要发送那么 IP 层就要进行分片把数据分片成若干片保证每一个分片都小于 MTU。把一份 IP 数据报进行分片以后由目标主机的 IP 层来进行重新组装后在交给上一层 TCP 传输层。这看起来井然有序但这存在隐患的那么当如果一个 IP 分片丢失整个 IP 报文的所有分片都得重传。因为 IP 层本身没有超时重传机制它由传输层的 TCP 来负责超时和重传。当接收方发现 TCP 报文头部 数据的某一片丢失后则不会响应 ACK 给对方那么发送方的 TCP 在超时后就会重发「整个 TCP 报文头部 数据」。因此可以得知由 IP 层进行分片传输是非常没有效率的。所以为了达到最佳的传输效能 TCP 协议在建立连接的时候通常要协商双方的 MSS 值当 TCP 层发现数据超过 MSS 时则就先会进行分片当然由它形成的 IP 包的长度也就不会大于 MTU 自然也就不用 IP 分片了。握手阶段协商 MSS经过 TCP 层分片后如果一个 TCP 分片丢失后进行重发时也是以 MSS 为单位而不用重传所有的分片大大增加了重传的效率。什么是 SYN 攻击如何避免 SYN 攻击SYN 攻击我们都知道 TCP 连接建立是需要三次握手假设攻击者短时间伪造不同 IP 地址的 SYN 报文服务端每接收到一个 SYN 报文就进入SYN_RCVD 状态但服务端发送出去的 ACK SYN 报文无法得到未知 IP 主机的 ACK 应答久而久之就会占满服务端的 SYN 接收队列未连接队列使得服务器不能为正常用户服务。SYN 攻击避免 SYN 攻击方式一其中一种解决方式是通过修改 Linux 内核参数控制队列大小和当队列满时应做什么处理。当网卡接收数据包的速度大于内核处理的速度时会有一个队列保存这些数据包。控制该队列的最大值如下参数net.core.netdev_max_backlogSYN_RCVD 状态连接的最大个数net.ipv4.tcp_max_syn_backlog 超出处理能时对新的 SYN 直接回 RST丢弃连接net.ipv4.tcp_abort_on_overflow 避免 SYN 攻击方式二我们先来看下Linux 内核的 SYN 未完成连接建立队列与 Accpet 已完成连接建立队列是如何工作的正常流程正常流程当服务端接收到客户端的 SYN 报文时会将其加入到内核的「 SYN 队列」接着发送 SYN ACK 给客户端等待客户端回应 ACK 报文服务端接收到 ACK 报文后从「 SYN 队列」移除放入到「 Accept 队列」应用通过调用 accpet() socket 接口从「 Accept 队列」取出的连接。应用程序过慢应用程序过慢如果应用程序过慢时就会导致「 Accept 队列」被占满。受到 SYN 攻击受到 SYN 攻击如果不断受到 SYN 攻击就会导致「 SYN 队列」被占满。tcp_syncookies 的方式可以应对 SYN 攻击的方法net.ipv4.tcp_syncookies  1tcp_syncookies 应对 SYN 攻击当 「 SYN 队列」满之后后续服务器收到 SYN 包不进入「 SYN 队列」计算出一个 cookie 值再以 SYN ACK 中的「序列号」返回客户端服务端接收到客户端的应答报文时服务器会检查这个 ACK 包的合法性。如果合法直接放入到「 Accept 队列」。最后应用通过调用 accpet() socket 接口从「 Accept 队列」取出的连接。03 TCP 连接断开TCP 四次挥手过程和状态变迁天下没有不散的宴席对于 TCP 连接也是这样 TCP 断开连接是通过四次挥手方式。双方都可以主动断开连接断开连接后主机中的「资源」将被释放。客户端主动关闭连接 —— TCP 四次挥手客户端打算关闭连接此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文也即 FIN 报文之后客户端进入 FIN_WAIT_1 状态。服务端收到该报文后就向客户端发送 ACK 应答报文接着服务端进入 CLOSED_WAIT 状态。客户端收到服务端的 ACK 应答报文后之后进入 FIN_WAIT_2 状态。等待服务端处理完数据后也向客户端发送 FIN 报文之后服务端进入 LAST_ACK 状态。客户端收到服务端的 FIN 报文后回一个 ACK 应答报文之后进入 TIME_WAIT 状态服务器收到了 ACK 应答报文后就进入了 CLOSE 状态至此服务端已经完成连接的关闭。客户端在经过 2MSL 一段时间后自动进入 CLOSE 状态至此客户端也完成连接的关闭。你可以看到每个方向都需要一个 FIN 和一个 ACK因此通常被称为四次挥手。这里一点需要注意是主动关闭连接的才有 TIME_WAIT 状态。为什么挥手需要四次再来回顾下四次挥手双方发 FIN 包的过程就能理解为什么需要四次了。关闭连接时客户端向服务端发送 FIN 时仅仅表示客户端不再发送数据了但是还能接收数据。服务器收到客户端的 FIN 报文时先回一个 ACK 应答报文而服务端可能还有数据需要处理和发送等服务端不再发送数据时才发送 FIN 报文给客户端来表示同意现在关闭连接。从上面过程可知服务端通常需要等待完成数据的发送和处理所以服务端的 ACK 和 FIN 一般都会分开发送从而比三次握手导致多了一次。为什么 TIME_WAIT 等待的时间是 2MSLMSL 是 Maximum Segment Lifetime报文最大生存时间它是任何报文在网络上存在的最长时间超过这个时间报文将被丢弃。因为 TCP 报文基于是 IP 协议的而 IP 头中有一个 TTL 字段是 IP 数据报可以经过的最大路由数每经过一个处理他的路由器此值就减 1当此值为 0 则数据报将被丢弃同时发送 ICMP 报文通知源主机。MSL 与 TTL 的区别MSL 的单位是时间而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL 消耗为 0 的时间以确保报文已被自然消亡。TIME_WAIT 等待 2 倍的 MSL比较合理的解释是网络中可能存在来自发送方的数据包当这些发送方的数据包被接收方处理后又会向对方发送响应所以一来一回需要等待 2 倍的时间。比如如果被动关闭方没有收到断开连接的最后的 ACK 报文就会触发超时重发 Fin 报文另一方接收到 FIN 后会重发 ACK 给被动关闭方 一来一去正好 2 个 MSL。2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内因为客户端的 ACK 没有传输到服务端客户端又接收到了服务端重发的 FIN 报文那么 2MSL 时间将重新计时。在 Linux 系统里 2MSL 默认是 60 秒那么一个 MSL 也就是 30 秒。Linux 系统停留在 TIME_WAIT 的时间为固定的 60 秒。其定义在 Linux 内核代码里的名称为 TCP_TIMEWAIT_LEN#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT state, about 60 seconds  */ 如果要修改 TIME_WAIT 的时间长度只能修改 Linux 内核代码里 TCP_TIMEWAIT_LEN 的值并重新编译 Linux 内核。为什么需要 TIME_WAIT 状态主动发起关闭连接的一方才会有 TIME-WAIT 状态。需要 TIME-WAIT 状态主要是两个原因防止具有相同「四元组」的「旧」数据包被收到保证「被动关闭连接」的一方能被正确的关闭即保证最后的 ACK 能让被动关闭方接收从而帮助其正常关闭原因一防止旧连接的数据包假设 TIME-WAIT 没有等待时间或时间过短被延迟的数据包抵达后会发生什么呢接收到历史数据的异常如上图黄色框框服务端在关闭连接之前发送的 SEQ 301 报文被网络延迟了。这时有相同端口的 TCP 连接被复用后被延迟的 SEQ 301 抵达了客户端那么客户端是有可能正常接收这个过期的报文这就会产生数据错乱等严重的问题。所以TCP 就设计出了这么一个机制经过 2MSL 这个时间足以让两个方向上的数据包都被丢弃使得原来连接的数据包在网络中都自然消失再出现的数据包一定都是新建立连接所产生的。原因二保证连接正确关闭在 RFC 793 指出 TIME-WAIT 另一个重要的作用是TIME-WAIT - represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request.也就是说TIME-WAIT 作用是等待足够的时间以确保最后的 ACK 能让被动关闭方接收从而帮助其正常关闭。假设 TIME-WAIT 没有等待时间或时间过短断开连接会造成什么问题呢没有确保正常断开的异常如上图红色框框客户端四次挥手的最后一个 ACK 报文如果在网络中被丢失了此时如果客户端 TIME-WAIT 过短或没有则就直接进入了 CLOSE 状态了那么服务端则会一直处在 LASE-ACK 状态。当客户端发起建立连接的 SYN 请求报文后服务端会发送 RST 报文给客户端连接建立的过程就会被终止。如果 TIME-WAIT 等待足够长的情况就会遇到两种情况服务端正常收到四次挥手的最后一个 ACK 报文则服务端正常关闭连接。服务端没有收到四次挥手的最后一个 ACK 报文时则会重发 FIN 关闭连接报文并等待新的 ACK 报文。所以客户端在 TIME-WAIT 状态等待 2MSL 时间后就可以保证双方的连接都可以正常的关闭。TIME_WAIT 过多有什么危害如果服务器有处于 TIME-WAIT 状态的 TCP则说明是由服务器方主动发起的断开请求。过多的 TIME-WAIT 状态主要的危害有两种第一是内存资源占用第二是对端口资源的占用一个 TCP 连接至少消耗一个本地端口第二个危害是会造成严重的后果的要知道端口资源也是有限的一般可以开启的端口为 3276861000也可以通过如下参数设置指定net.ipv4.ip_local_port_range 如果服务端 TIME_WAIT 状态过多占满了所有端口资源则会导致无法创建新连接。如何优化 TIME_WAIT这里给出优化 TIME-WAIT 的几个方式都是有利有弊打开 net.ipv4.tcp_tw_reuse 和 net.ipv4.tcp_timestamps 选项net.ipv4.tcp_max_tw_buckets程序中使用 SO_LINGER 应用强制使用 RST 关闭。方式一net.ipv4.tcp_tw_reuse 和 tcp_timestamps如下的 Linux 内核参数开启后则可以复用处于 TIME_WAIT 的 socket 为新的连接所用。net.ipv4.tcp_tw_reuse  1 使用这个选项还有一个前提需要打开对 TCP 时间戳的支持即net.ipv4.tcp_timestamps1默认即为 1 这个时间戳的字段是在 TCP 头部的「选项」里用于记录 TCP 发送方的当前时间戳和从对端接收到的最新时间戳。由于引入了时间戳我们在前面提到的 2MSL 问题就不复存在了因为重复的数据包会因为时间戳过期被自然丢弃。温馨提醒net.ipv4.tcp_tw_reuse要慎用因为使用了它就必然要打开时间戳的支持 net.ipv4.tcp_timestamps当客户端与服务端主机时间不同步时客户端的发送的消息会被直接拒绝掉。小林在工作中就遇到过。。。排查了非常的久方式二net.ipv4.tcp_max_tw_buckets这个值默认为 18000当系统中处于 TIME_WAIT 的连接一旦超过这个值时系统就会将所有的 TIME_WAIT 连接状态重置。这个方法过于暴力而且治标不治本带来的问题远比解决的问题多不推荐使用。方式三程序中使用 SO_LINGER我们可以通过设置 socket 选项来设置调用 close 关闭连接行为。struct linger so_linger; so_linger.l_onoff  1; so_linger.l_linger  0; setsockopt(s, SOL_SOCKET, SO_LINGER, so_linger,sizeof(so_linger)); 如果l_onoff为非 0 且l_linger值为 0那么调用close后会立该发送一个RST标志给对端该 TCP 连接将跳过四次挥手也就跳过了TIME_WAIT状态直接关闭。但这为跨越TIME_WAIT状态提供了一个可能不过是一个非常危险的行为不值得提倡。如果已经建立了连接但是客户端突然出现故障了怎么办TCP 有一个机制是保活机制。这个机制的原理是这样的定义一个时间段在这个时间段内如果没有任何连接相关的活动TCP 保活机制会开始作用每隔一个时间间隔发送一个探测报文该探测报文包含的数据非常少如果连续几个探测报文都没有得到响应则认为当前的 TCP 连接已经死亡系统内核将错误信息通知给上层应用程序。在 Linux 内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔以下都为默认值net.ipv4.tcp_keepalive_time7200 net.ipv4.tcp_keepalive_intvl75   net.ipv4.tcp_keepalive_probes9tcp_keepalive_time7200表示保活时间是 7200 秒2小时也就 2 小时内如果没有任何连接相关的活动则会启动保活机制tcp_keepalive_intvl75表示每次检测间隔 75 秒tcp_keepalive_probes9表示检测 9 次无响应认为对方是不可达的从而中断本次的连接。也就是说在 Linux 系统中最少需要经过 2 小时 11 分 15 秒才可以发现一个「死亡」连接。这个时间是有点长的我们也可以根据实际的需求对以上的保活相关的参数进行设置。如果开启了 TCP 保活需要考虑以下几种情况第一种对端程序是正常工作的。当 TCP 保活的探测报文发送给对端, 对端会正常响应这样 TCP 保活时间会被重置等待下一个 TCP 保活时间的到来。第二种对端程序崩溃并重启。当 TCP 保活的探测报文发送给对端后对端是可以响应的但由于没有该连接的有效信息会产生一个 RST 报文这样很快就会发现 TCP 连接已经被重置。第三种是对端程序崩溃或对端由于其他原因导致报文不可达。当 TCP 保活的探测报文发送给对端后石沉大海没有响应连续几次达到保活探测次数后TCP 会报告该 TCP 连接已经死亡。03 Socket 编程针对 TCP 应该如何 Socket 编程基于 TCP 协议的客户端和服务器工作服务端和客户端初始化 socket得到文件描述符服务端调用 bind将绑定在 IP 地址和端口;服务端调用 listen进行监听服务端调用 accept等待客户端连接客户端调用 connect向服务器端的地址和端口发起连接请求服务端 accept 返回用于传输的 socket 的文件描述符客户端调用 write 写入数据服务端调用 read 读取数据客户端断开连接时会调用 close那么服务端 read 读取数据的时候就会读取到了 EOF待处理完数据后服务端调用 close表示连接关闭。这里需要注意的是服务端调用 accept 时连接成功了会返回一个已完成连接的 socket后续用来传输数据。所以监听的 socket 和真正用来传送数据的 socket是「两个」 socket一个叫作监听 socket一个叫作已完成连接 socket。成功连接建立之后双方开始通过 read 和 write 函数来读写数据就像往一个文件流里面写东西一样。listen 时候参数 backlog 的意义Linux内核中会维护两个队列未完成连接队列SYN 队列接收到一个 SYN 建立连接请求处于 SYN_RCVD 状态已完成连接队列Accpet 队列已完成 TCP 三次握手过程处于 ESTABLISHED 状态SYN 队列 与 Accpet 队列int listen (int socketfd, int backlog)参数一 socketfd 为 socketfd 文件描述符参数二 backlog这参数在历史有一定的变化在早期 Linux 内核 backlog 是 SYN 队列大小也就是未完成的队列大小。在 Linux 内核 2.2 之后backlog 变成 accept 队列也就是已完成连接建立的队列长度所以现在通常认为 backlog 是 accept 队列。accept 发送在三次握手的哪一步我们先看看客户端连接服务端时发送了什么客户端连接服务端客户端的协议栈向服务器端发送了 SYN 包并告诉服务器端当前发送序列号 client_isn客户端进入 SYNC_SENT 状态服务器端的协议栈收到这个包之后和客户端进行 ACK 应答应答的值为 client_isn1表示对 SYN 包 client_isn 的确认同时服务器也发送一个 SYN 包告诉客户端当前我的发送序列号为 server_isn服务器端进入 SYNC_RCVD 状态客户端协议栈收到 ACK 之后使得应用程序从 connect 调用返回表示客户端到服务器端的单向连接建立成功客户端的状态为 ESTABLISHED同时客户端协议栈也会对服务器端的 SYN 包进行应答应答数据为 server_isn1应答包到达服务器端后服务器端协议栈使得 accept 阻塞调用返回这个时候服务器端到客户端的单向连接也建立成功服务器端也进入 ESTABLISHED 状态。从上面的描述过程我们可以得知客户端 connect 成功返回是在第二次握手服务端 accept 成功返回是在三次握手成功之后。客户端调用 close 了连接是断开的流程是什么我们看看客户端主动调用了 close会发生什么客户端调用 close 过程客户端调用 close表明客户端没有数据需要发送了则此时会向服务端发送 FIN 报文进入 FIN_WAIT_1 状态服务端接收到了 FIN 报文TCP 协议栈会为 FIN 包插入一个文件结束符 EOF 到接收缓冲区中应用程序可以通过 read 调用来感知这个 FIN 包。这个 EOF 会被放在已排队等候的其他已接收的数据之后这就意味着服务端需要处理这种异常情况因为 EOF 表示在该连接上再无额外数据到达。此时服务端进入 CLOSE_WAIT 状态接着当处理完数据后自然就会读到 EOF于是也调用 close 关闭它的套接字这会使得会发出一个 FIN 包之后处于 LAST_ACK 状态客户端接收到服务端的 FIN 包并发送 ACK 确认包给服务端此时客户端将进入 TIME_WAIT 状态服务端收到 ACK 确认包后就进入了最后的 CLOSE 状态客户端进过 2MSL 时间之后也进入 CLOSED 状态巨人的肩膀[1] 趣谈网络协议专栏.刘超.极客时间.[2] 网络编程实战专栏.盛延敏.极客时间.[3] 计算机网络-自顶向下方法.陈鸣 译.机械工业出版社[4] TCP/IP详解 卷1协议.范建华 译.机械工业出版社[5] 图解TCP/IP.竹下隆史.人民邮电出版社[6] https://www.rfc-editor.org/rfc/rfc793.html[7] https://draveness.me/whys-the-design-tcp-three-way-handshake[9] https://draveness.me/whys-the-design-tcp-time-wait9个小技巧让你的 if else看起来更优雅String性能提升10倍的几个方法(源码原理分析)关注公众号发送”进群“老王拉你进读者群。
http://www.zqtcl.cn/news/903680/

相关文章:

  • 政务公开网站建设的亮点和建议wordpress注册怎么设置密码
  • 外贸有哪些网站成都网络营销搜索推广优势
  • 国外mod大型网站财税公司
  • 一个很好的个人网站开发做一个简单网页多少钱
  • 东莞在哪里学网站建设网站建设团队与分工
  • 网站功能插件昆明网站建设技术研发中心
  • 网站开发培训中心 市桥移动端ui
  • 高碑店地区网站建设上海排名十大装潢公司
  • 无锡自助建站网站还是新能源专业好
  • pc 手机网站 微站如何建设与维护网站
  • 大学生兼职网站开发毕设论文杭州网络排名优化
  • 做教育机器网站网站建设的步骤图
  • 桔子建站是什么平台郑州公司注册网上核名
  • 网站开发技能有哪些网站建设艾金手指科杰
  • 网站建设挂什么费用网站建设学那些课
  • 网站定位与功能分析在互联网公司做网站
  • 安阳网站建设兼职做网站推广有哪些公司
  • 网站制作的一般过程怎么用手机搭建网站
  • 备案 网站名称 怎么改深圳建网站公司
  • html 企业网站模板网站策划书免费
  • 网站建设销售ppt拖拽建站系统源码
  • 网站托管费用多少网站的开发流程
  • 周到的商城网站建设北京品牌网站
  • 网站开发费用属于什么科目网站建设考试多选题
  • c asp做网站wordpress4.5.2文章采集
  • 百度网站建设电话建立网站站建设可以吗
  • 网站后台代码在哪修改网站如何做下一页
  • 网站开发职业要求百度推广代理商与总公司的区别
  • 西安网站建设中心网页 网 址网站区别
  • 技术支持东莞网站建设机械seo岗位是什么意思