TCP 连接状态标识 | SYN, FIN, ACK, PSH, RST, URG
注:本文为“TCP 连接状态标识”相关文章合辑。
TCP 的状态:SYN, FIN, ACK, PSH, RST, URG 简介及 ACK 确认机制
llzhang_fly 于 2020-09-19 05:25:26 发布
1、TCP 的状态 FLAGS 字段状态
- 在 TCP 层,有个 FLAGS 字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG.
对于我们日常的分析有用的就是前面的五个字段它们的含义是:
SYN 表示建立连接,
FIN 表示关闭连接,
ACK 表示响应,
PSH 表示有 DATA 数据传输,
RST 表示连接重置。
其中,ACK 是可能与 SYN,FIN 等同时使用的,比如:SYN 和 ACK 可能同时为 1,它表示的就是建立连接之后的响应, 如果只是单个的一个 SYN,它表示的只是建立连接。TCP 的几次握手就是通过这样的 ACK 表现出来的。
但 SYN 与 FIN 是不会同时为 1 的,因为前者表示的是建立连接,而后者表示的是断开连接。
RST 一般是在 FIN 之后才会出现为 1 的情况,表示的是连接重置。 一般地,当出现 FIN 包或 RST 包时,我们便认为客户端与服务器端断开了连接;而当出现 SYN 和 SYN+ACK 包时,我们认为客户端与服务器建立了一个连接。
PSH 为 1 的情况,一般只出现在 DATA 内容不为 0 的包中,也就是说 PSH 为 1 表示的是有真正的 TCP 数据包内容被传递。
- TCP 的连接建立和连接关闭,都是通过请求-响应的模式完成的。
概念补充 - TCP 三次握手:
TCP(Transmission Control Protocol) 传输控制协议
TCP 是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:
位码即 tcp 标志位,有 6 种标示:SYN(synchronous 建立联机) ACK(acknowledgement 确认) PSH(push 传送) FIN(finish 结束) RST(reset 重置) URG(urgent 紧急) Sequence number(顺序号码) Acknowledge number(确认号码)
第一次握手:主机 A 发送位码为 syn=1,随机产生 seq number=1234567 的数据包到服务器,主机 B 由 SYN=1 知道,A 要求建立联机;
第二次握手:主机 B 收到请求后要确认联机信息,向 A 发送 ack number=(主机 A 的 seq+1),syn=1,ack=1,随机产生 seq=7654321 的包;
第三次握手:主机 A 收到后检查 ack number 是否正确,即第一次发送的 seq number+1,以及位码 ack 是否为 1,若正确,主机 A 会再发送 ack number=(主机 B 的 seq+1),ack=1,主机 B 收到后确认 seq 值与 ack=1 则连接建立成功。
完成三次握手,主机 A 与主机 B 开始传送数据。
2、Wireshark TCP 报文到达 ACK 确认机制
转载:
- Wireshark TCP 报文到达 ACK 确认机制_whireshark ack-CSDN 博客
https://blog.csdn.net/chenlycly/article/details/74028616
TCP 数据包中的序列号(Sequence Number) 不是以报文段来进行编号的,而是 将连接生存周期内传输的所有数据当作一个字节流,序列号就是整个字节流中每个字节的编号。一个 TCP 数据包中包含多个字节流的数据(即数据段),而且每个 TCP 数据包中的数据大小不一定相同。在建立 TCP 连接的三次握手过程中,通信双方各自已确定了初始的序号 x 和 y,TCP 每次传送的报文段中的序号字段值表示所要传送本报文中的第一个字节的序号。
TCP 的报文到达确认(ACK),是对接收到的数据的最高序列号的确认,表示这前面的数据已经接收到,并向发送端返回一个下次接收时期望的 TCP 数据包的序列号(Ack Number) 。例如,主机 A 发送的当前数据序号是 400,数据长度是 100,则接收端收到后会返回一个确认号是 500 的确认号给主机 A。
TCP 提供的确认机制,可以在通信过程中可以不对每一个 TCP 数据包发出单独的确认包(Delayed ACK 机制),而是在传送数据时,顺便把确认信息传出,这样可以大大提高网络的利用率和传输效率。同时,TCP 的确认机制,也可以一次确认多个数据报,例如,接收方收到了 201,301,401 的数据报,则只需要对 401 的数据包进行确认即可,对 401 的数据包的确认也意味着 401 之前的所有数据包都已经确认,这样也可以提高系统的效率。
若发送方在规定时间内没有收到接收方的确认信息,就要将未被确认的数据包重新发送。接收方如果收到一个有差错的报文,则丢弃此报文,并不向发送方发送确认信息。因此,TCP 报文的重传机制是由设置的超时定时器来决定的,在定时的时间内没有收到确认信息,则进行重传。 这个定时的时间值的设定非常重要,太大会使包重传的延时比较大,太小则可能没有来得及收到对方的确认包发送方就再次重传,会使网络陷入无休止的重传过程中。接收方如果收到了重复的报文,将会丢弃重复的报文,但是必须发回确认信息,否则对方会再次发送。 丢包重传直到收到 ACK 报文或发送方达到配置的最大重传次数,最大重传次数取决于发送操作系统的配置值。默认情况下,Windows 主机默认重传 5 次。大多数 Linux 系统默认最大 15 次。两种操作系统都可配置。
TCP 协议应当保证数据报按序到达接收方。如果接收方收到的数据报文没有错误,只是未按序号,这种现象如何处理呢?TCP 协议本身没有规定,而是由 TCP 协议的实现者自己去确定。通常有两种方法进行处理:一是对没有按序号到达的报文直接丢弃,二是将未按序号到达的数据包先放于缓冲区内,等待它前面的序号包到达后,再将它交给应用进程。后一种方法将会提高系统的效率。例如,发送方连续发送了每个报文中 100 个字节的 TCP 数据报,其序号分别是 1,101,201,…,701。假如其它数据报都收到了,而 201 这个数据报没有收到,则接收端应当对 1 和 101 这两个数据报进行确认,并将数据递交给相关的应用进程,301 至 701 这 5 个数据报则应当放于缓冲区,等到 201 这个数据报到达后,然后按序将 201 至 701 这些数据报递交给相关应用进程,并对 701 数据报进行确认,确保了应用进程级的 TCP 数据的按序到达。
3、TCP 抓包分析
总结:
1、ACK 包可以和其他包合在一起,比如 ACK 包可以携带数据
2、可以接收多个数据包后,一次性给一个应答,不用每个数据包一一对应给应答
3、在通信过程中,通过接收到的包的 ack 值可以判断是否是上一个本机发送包的应答包(ack 值与上一个本机发送包的 seq 有关),seq 值和 ack 值的确定规则如下:
三次握手:
第一次握手(发送):seq 为 x(x 为任意值),无视 ack(因为是第一个包,不需要给其他包应答)
第二次握手(发送):seq 为 y(y 为任意值),ack 等于接收包 seq+1(即 x+1)
第三次握手(发送):seq 等于上一个本机发送包 seq+1(即 x+1),也就是 1,ack 等于接收包 seq+1(即 y+1)
数据传输:
某主机发送的 seq 和 ack 是根据上一个接收包的 seq、ack 和 len 得到,具体为:seq=ack,ack=seq+len
提醒:如果某一主机连续发了 4 个包,后三个包的 seq 和 ack 和第一个包的一样
提醒:seq 会单调增大
特别:如果握手完第一个数据包是客户端发送,第一个数据包的 seq 和 ack 和第三次握手的一样
四次挥手:
如果是服务器发起的挥手,挥手前最后一个包是服务器发送:
如果是客户端发起的挥手,挥手前最后一个包是客户端发送:
第一次挥手(发送):seq 为上一个本机发送包 seq+len,ack 为上一个本机发送包 ack
第二个挥手(发送):seq 为本次接收包 ack,ack 为本次接收包 seq+1
第三次挥手(发送):和第二次挥手一样
第四次挥手(发送):seq 为本次接收包 ack,ack 为本次接收包 seq+1
如果是服务器发起的挥手,挥手前最后一个包是客户端发送:
如果是客户端发起的挥手,挥手前最后一个包是服务器发送:
第一次挥手(发送):seq 为本次接收包 ack,ack 为本次接收包 seq+len
第二个挥手(发送):seq 为本次接收包 ack,ack 为本次接收包 seq+1
第三次挥手(发送):和第二次挥手一样
第四次挥手(发送):seq 为本次接收包 ack,ack 为本次接收包 seq+1
4、TCP 包的 seq 和 ack 号计算方法
https://blog.csdn.net/huaishu/article/details/93739446
5、使用 wireshark 出现很多 TCP Retransmission 信息
http://blog.jues.org.cn/post/shi-yong-wireshark-chu-xian-hen-duo-tcp-retransmission-xin-xi.html
出现 TCP Retransmission 多数是因为目标主机的端口没开有开放监听,很少出现是网络不好导致的。
如果在某个时间段(RTT 的倍数)内没有确认发送的数据,则将数据重新传输到远程主机。重传超时从 RTT 开始,并随着每次重传而增加一倍。 重传超时总是受限于 CFGZ-MNRTO 和 CFGYMax RTO。如果自从第一次传输数据以来,CFGY-ReTrExtTMO 时间就过去了,连接被关闭,即状态被设置为关闭。注意,当一个套接字被关闭时,将响应于接收到的端口所发送的任何数据包来发送重置。
当超时发生时,将重新发送输出窗口中的所有未确认数据。数据被重新打包,因此,包将不与原始包相同。例如,如果以 10 字节的数据发送分组,则发送具有 30 字节数据的分组,并且第一分组丢失,40 字节的未确认数据将在输出窗口中。当超时发生时,所有 40 个字节将在一个分组中发送(假设 MSS 大于或等于 40)。
如果接收到三个重复的确认,则快速重传算法无需等待超时即可重传 TCP 数据。RTIP32 还实现了 RFC 2582 中定义的 NeReNeO 快速恢复算法。
转载:https://blog.csdn.net/lemontree1945/article/details/88581516
类似场景:client 连接服务器时,因 TLS 证书设置错误,所以会导致连接服务器后,没有收到应答;即发送 SYN 报文,无响应
TCP 的连接状态标识(SYN, FIN, ACK, PSH, RST, URG)
m0_37989944 于 2021-09-03 18:47:59 发布
TCP 层,有个 FLAGS 字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG.
其中,对于我们日常的分析有用的就是前面的五个字段。它们的含义是:
(1)SYN 表示建立连接,
(2)FIN 表示关闭连接,
(3)ACK 表示响应,
(4)PSH 表示有 DATA 数据传输,
(5)RST 表示连接重置。
其中,ACK 是可能与 SYN,FIN 等同时使用的,比如 SYN 和 ACK 可能同时为 1,它表示的就是建立连接之后的响应,
如果只是单个的一个 SYN,它表示的只是建立连接。
TCP 的几次握手就是通过这样的 ACK 表现出来的。
但 SYN 与 FIN 是不会同时为 1 的,因为前者表示的是建立连接,而后者表示的是断开连接。
RST 一般是在 FIN 之后才会出现为 1 的情况,表示的是连接重置。
一般地,当出现 FIN 包或 RST 包时,我们便认为客户端与服务器端断开了连接;而当出现 SYN 和 SYN+ACK 包时,我们认为客户端与服务器建立了一个连接。
PSH 为 1 的情况,一般只出现在 DATA 内容不为 0 的包中,也就是说 PSH 为 1 表示的是有真正的 TCP 数据包内容被传递。
TCP 的连接建立和连接关闭,都是通过请求-响应的模式完成的。
概念补充 - TCP 三次握手:
TCP(Transmission Control Protocol) 传输控制协议
TCP 是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:
位码即 tcp 标志位,有 6 种标示:SYN(synchronous 建立联机) ACK(acknowledgement 确认) PSH(push 传送) FIN(finish 结束) RST(reset 重置) URG(urgent 紧急) Sequence number(顺序号码) Acknowledge number(确认号码)
第一次握手:主机 A 发送位码为 syn=1,随机产生 seq number=1234567 的数据包到服务器,主机 B 由 SYN=1 知道,A 要求建立联机;
第二次握手:主机 B 收到请求后要确认联机信息,向 A 发送 ack number=(主机 A 的 seq+1),syn=1,ack=1,随机产生 seq=7654321 的包;
第三次握手:主机 A 收到后检查 ack number 是否正确,即第一次发送的 seq number+1,以及位码 ack 是否为 1,若正确,主机 A 会再发送 ack number=(主机 B 的 seq+1),ack=1,主机 B 收到后确认 seq 值与 ack=1 则连接建立成功。
完成三次握手,主机 A 与主机 B 开始传送数据。
在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送 syn 包(syn=j) 到服务器,并进入 SYN_SEND 状态,等待服务器确认;
第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;
第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。完成三次握手,客户端与服务器开始传送数据。
【注意】中断连接端可以是 Client 端,也可以是 Server 端。
假设 Client 端发起中断连接请求,也就是发送 FIN 报文。Server 端接到 FIN 报文后,意思是说 “我 Client 端没有数据要发给你了”,但是如果你还有数据没有发送完成,则不必急着关闭 Socket,可以继续发送数据。所以你先发送 ACK,“告诉 Client 端,你的请求我收到了,但是我还没准备好,请继续你等我的消息”。这个时候 Client 端就进入 FIN_WAIT 状态,继续等待 Server 端的 FIN 报文。当 Server 端确定数据已发送完成,则向 Client 端发送 FIN 报文,“告诉 Client 端,好了,我这边数据发完了,准备好关闭连接了”。Client 端收到 FIN 报文后,“就知道可以关闭连接了,但是他还是不相信网络,怕 Server 端不知道要关闭,所以发送 ACK 后进入 TIME_WAIT 状态,如果 Server 端没有收到 ACK 则可以重传。“,Server 端收到 ACK 后,” 就知道可以断开连接了 "。Client 端等待了 2MSL后依然没有收到回复,则证明 Server 端已正常关闭,那好,我 Client 端也可以关闭连接了。Ok,TCP 连接就这样关闭了!
整个过程 Client 端所经历的状态如下:
而 Server 端所经历的过程如下:
【注意】 在 TIME_WAIT 状态中,如果 TCP client 端最后一次发送的 ACK 丢失了,它将重新发送。TIME_WAIT 状态中所需要的时间是依赖于实现方法的。典型的值为 30 秒、1 分钟和 2 分钟。等待之后连接正式关闭,并且所有的资源(包括端口号) 都被释放。
【问题 1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当 Server 端收到 Client 端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。但是关闭连接时,当 Server 端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉 Client 端,“你发的 FIN 报文我收到了”。只有等到我 Server 端所有的报文都发送完了,我才能发送 FIN 报文,因此不能一起发送。故需要四步握手。
【问题 2】为什么 TIME_WAIT 状态需要经过 2MSL(最大报文段生存时间) 才能返回到 CLOSE 状态?
答:虽然按道理,四个报文都发送完毕,我们可以直接进入 CLOSE 状态了,但是我们必须假象网络是不可靠的,有可以最后一个 ACK 丢失。所以 TIME_WAIT 状态就是用来重发可能丢失的 ACK 报文。
10054 错位码
有人问:select 写 socket 时候 建立链接立马发送数据有时候收不到数据 还提示 10054 ,大多数的况还是能收到的 一般收不到数据的时候 第二次再链接发送数据就能收到 请问是怎么回事呢?
对于好奇心极强的我,对于这个没遇到的问题,我就百度了 10054 错误。网上说:
一般来说是连接被对方重设。一个建立的连接被远程主机强行关闭,若远程主机上的进程异常终止运行(由于内存冲突或硬件故障),或者针对套接字执行了一次强行关闭,便会产生 10054 错误。针对强行关闭的情况,可用 SO_LINGER 套接字选项和 setsockopt 来配置一个套接字。
而对于 群里描述的那个问题,我回忆了 TCP/IP 协议,我认为会有如下两种情况:
(1)client 在与 server 进行三次握手时,client 调用 connect 函数完成了连接的建立(客户端自以为建立了),而实际 server 那边却没有收到最后一次握手 ack 的回复。这时触发了 server 的 syn 触发器,重发 SYN+ACK 包,一般默认是重发 5 次,时间分别是 1 秒、2 秒、4 秒、8 秒、16 秒;而此时 client 马上发送数据的话,server 会发 RST 回复给 client, 那么此时 client 就会提示 10054。
(2)而另一种情况就是 server 这边的 accept 队列满了(一般有 syn_recv 队列,accept 队列),那么此时 server 会直接回复 RST(最新的 linux 内核是这么实现的),当然也有可能会拒绝 client 的请求,让 client 自己自动断开请求。
群里的一位大神(冒泡)说实现第二种方式,也就是拒绝 client 发过来的请求,原因如下:
第一,服务器已经处理不过来了,再发 rst 加剧压力
第二,客户端如果丢包,会等到超时再重试,而收到 rst 的话有可能立刻重试,服务器压力会更大。
Linux 网络编程中 socket 常见错误码分析
EINTR: 4
阻塞的操作被取消阻塞的调用打断。如设置了发送接收超时,就会遇到这种错误。
只能针对阻塞模式的 socket。读,写阻塞的 socket 时,-1 返回,错误号为 INTR。另外,如果出现 EINTR 即 errno 为 4,错误描述 Interrupted system call,操作也应该继续。如果 recv 的返回值为 0,那表明连接已经断开,接收操作也应该结束。
ETIMEOUT:110
1、操作超时。一般设置了发送接收超时,遇到网络繁忙的情况,就会遇到这种错误。
2、服务器做了读数据做了超时限制,读时发生了超时。
3、错误被描述为 “connect time out”,即 “连接超时”,这种情况一般发生在服务器主机崩溃。此时客户 TCP 将在一定时间内(依具体实现)持续重发数据分节,试图从服务 TCP 获得一个 ACK 分节。当最终放弃尝试后(此时服务器未重新启动),内核将会向客户进程返回 ETIMEDOUT 错误。如果某个中间路由器判定该服务器主机已经不可达,则一般会响应 “destination unreachable”-“目的地不可达” 的 ICMP 消息,相应的客户进程返回的错误是 EHOSTUNREACH 或 ENETUNREACH。当服务器重新启动后,由于 TCP 状态丢失,之前所有的连接信息也不存在了,此时对于客户端发来请求将回应 RST。如果客户进程对检测服务器主机是否崩溃很有必要,要求即使客户进程不主动发送数据也能检测出来,那么需要使用其它技术,如配置 SO_KEEPALIVE Socket 选项,或实现某些心跳函数。
EAGAIN:
1、Send 返回值小于要发送的数据数目,会返回 EAGAIN 和 EINTR。
2、recv 返回值小于请求的长度时说明缓冲区已经没有可读数据,但再读不一定会触发 EAGAIN,有可能返回 0 表示 TCP 连接已被关闭。
3、当 socket 是非阻塞时,如返回此错误,表示写缓冲队列已满,可以做延时后再重试.
4、在 Linux 进行非阻塞的 socket 接收数据时经常出现 Resource temporarily unavailable,errno 代码为 11(EAGAIN),表明在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏 socket 的同步,不用管它,下次循环接着 recv 就可以。对非阻塞 socket 而言,EAGAIN 不是一种错误。
EPIPE:
1、Socket 关闭,但是 socket 号并没有置 - 1。继续在此 socket 上进行 send 和 recv,就会返回这种错误。这个错误会引发 SIGPIPE 信号,系统会将产生此 EPIPE 错误的进程杀死。所以,一般在网络程序中,首先屏蔽此消息,以免发生不及时设置 socket 进程被杀死的情况。
2、write(…) on a socket that has been closed at the other end will cause a SIGPIPE.
3、错误被描述为 “broken pipe”,即 “管道破裂”,这种情况一般发生在客户进程不理会(或未及时处理)Socket 错误,继续向服务 TCP 写入更多数据时,内核将向客户进程发送 SIGPIPE 信号,该信号默认会使进程终止(此时该前台进程未进行 core dump)。结合上边的 ECONNRESET 错误可知,向一个 FIN_WAIT2 状态的服务 TCP(已 ACK 响应 FIN 分节)写入数据不成问题,但是写一个已接收了 RST 的 Socket 则是一个错误。
EBADF:
read(…) or write(…) on a locally closed socket will return EBADF
EFAULT:
地址错误。
EBUSY:
ECONNREFUSED:
1、拒绝连接。一般发生在连接建立时。
拔服务器端网线测试,客户端设置 keep alive 时,recv 较快返回 0, 先收到 ECONNREFUSED(Connection refused) 错误码,其后都是 ETIMEOUT。
2、an error returned from connect(), so it can only occur in a client(if a client is defined as the party that initiates the connection
ECONNRESET:
1、在客户端服务器程序中,客户端异常退出,并没有回收关闭相关的资源,服务器端会先收到 ECONNRESET 错误,然后收到 EPIPE 错误。
2、连接被远程主机关闭。有以下几种原因:远程主机停止服务,重新启动;当在执行某些操作时遇到失败,因为设置了 “keep alive” 选项,连接被关闭,一般与 ENETRESET 一起出现。
3、远程端执行了一个 “hard” 或者 “abortive” 的关闭。应用程序应该关闭 socket,因为它不再可用。当执行在一个 UDP socket 上时,这个错误表明前一个 send 操作返回一个 ICMP “port unreachable” 信息。
4、如果 client 关闭连接,server 端的 select 并不出错(不返回 - 1, 使用 select 对唯一一个 socket 进行 non- blocking 检测), 但是写该 socket 就会出错,用的是 send. 错误号:ECONNRESET. 读(recv) socket 并没有返回错误。
5、该错误被描述为 “connection reset by peer”,即 “对方复位连接”,这种情况一般发生在服务进程较客户进程提前终止。当服务进程终止时会向客户 TCP 发送 FIN 分节,客户 TCP 回应 ACK,服务 TCP 将转入 FIN_WAIT2 状态。此时如果客户进程没有处理该 FIN (如阻塞在其它调用上而没有关闭 Socket 时),则客户 TCP 将处于 CLOSE_WAIT 状态。当客户进程再次向 FIN_WAIT2 状态的服务 TCP 发送数据时,则服务 TCP 将立刻响应 RST。一般来说,这种情况还可以会引发另外的应用程序异常,客户进程在发送完数据后,往往会等待从网络 IO 接收数据,很典型的如 read 或 readline 调用,此时由于执行时序的原因,如果该调用发生在 RST 分节收到前执行的话,那么结果是客户进程会得到一个非预期的 EOF 错误。此时一般会输出 “server terminated prematurely”-“服务器过早终止” 错误。
EINVAL:
无效参数。提供的参数非法。有时也会与 socket 的当前状态相关,如一个 socket 并没有进入 listening 状态,此时调用 accept,就会产生 EINVAL 错误。
EMFILE:
打开了太多的 socket。对进程或者线程而言,每种实现方法都有一个最大的可用 socket 数目处理,或者是全局的,或者是局部的。
EWOULDBLOCK:EAGAIN
资源暂时不可用。这个错误是从对非阻塞 socket 进行的不能立即结束的操作返回的,如当没有数据在队列中可以读时,调用 recv。并不是 fatal 错误,稍后操作可以被重复。调用在一个非阻塞的 SOCK_STREAM socket 上调用 connect 时会产生这个错误,因为有时连接建立必须消耗一定的时间。
ENOTCONN
在一个没有建立连接的 socket 上,进行 read,write 操作会返回这个错误。出错的原因是 socket 没有标识地址。Setsoc 也可能会出错。
ECONNRESET
Connection reset by peer.
连接被远程主机关闭。有以下几种原因:远程主机停止服务,重新启动;当在执行某些操作时遇到失败,因为设置了 “keep alive” 选项,连接被关闭,一般与 ENETRESET 一起出现。
ECONNABORTED
1、软件导致的连接取消。一个已经建立的连接被 host 方的软件取消,原因可能是数据传输超时或者是协议错误。
2、该错误被描述为 “software caused connection abort”,即 “软件引起的连接中止”。原因在于当服务和客户进程在完成用于 TCP 连接的 “三次握手” 后,客户 TCP 却发送了一个 RST (复位)分节,在服务进程看来,就在该连接已由 TCP 排队,等着服务进程调用 accept 的时候 RST 却到达了。POSIX 规定此时的 errno 值必须 ECONNABORTED。源自 Berkeley 的实现完全在内核中处理中止的连接,服务进程将永远不知道该中止的发生。服务器进程一般可以忽略该错误,直接再次调用 accept。
当 TCP 协议接收到 RST 数据段,表示连接出现了某种错误,函数 read 将以错误返回,错误类型为 ECONNERESET。并且以后所有在这个套接字上的读操作均返回错误。错误返回时返回值小于 0。
ENETUNREACH
网络不可达。Socket 试图操作一个不可达的网络。这意味着 local 的软件知道没有路由到达远程的 host。
ENETRESET
网络重置时丢失连接。
由于设置了 “keep-alive” 选项,探测到一个错误,连接被中断。在一个已经失败的连接上试图使用 setsockopt 操作,也会返回这个错误。
EINPROGRESS:
操作正在进行中。一个阻塞的操作正在执行。
ENOTSOCK:
在非 socket 上执行 socket 操作。
EDESTADDRREQ:
需要提供目的地址。
在一个 socket 上的操作需要提供地址。如往一个 ADDR_ANY 地址上进行 sendto 操作会返回这个错误。
EMSGSIZE:
消息体太长。
发送到 socket 上的一个数据包大小比内部的消息缓冲区大,或者超过别的网络限制,或是用来接收数据包的缓冲区比数据包本身小。
EPROTOTYPE
协议类型错误。标识了协议的 Socket 函数在不支持的 socket 上进行操作。如 ARPA Internet
UDP 协议不能被标识为 SOCK_STREAM socket 类型。
ENOPROTOOPT
该错误不是一个 Socket 连接相关的错误。errno 给出该值可能由于,通过 getsockopt 系统调用来获得一个套接字的当前选项状态时,如果发现了系统不支持的选项参数就会引发该错误。
EPROTONOSUPPORT
不支持的协议。系统中没有安装标识的协议,或者是没有实现。如函数需要 SOCK_DGRAM socket,但是标识了 stream protocol.。
ESOCKTNOSUPPORT
Socket 类型不支持。指定的 socket 类型在其 address family 中不支持。如可选选中选项 SOCK_RAW,但实现并不支持 SOCK_RAW sockets。
连接过程可能出现的错误情况有:
(1) 如果客户机 TCP 协议没有接收到对它的 SYN 数据段的确认,函数以错误返回,错误类型为 ETIMEOUT。通常 TCP 协议在发送 SYN 数据段失败之后,会多次发送 SYN 数据段,在所有的发送都高中失败之后,函数以错误返回。
注:SYN(synchronize)位:请求连接。TCP 用这种数据段向对方 TCP 协议请求建立连接。在这个数据段中,TCP 协议将它选择的初始序列号通知对方,并且与对方协议协商最大数据段大小。SYN 数据段的序列号为初始序列号,这个 SYN 数据段能够被确认。当协议接收到对这个数据段的确认之后,建立 TCP 连接。
(2) 如果远程 TCP 协议返回一个 RST 数据段,函数立即以错误返回,错误类型为 ECONNREFUSED。当远程机器在 SYN 数据段指定的目的端口号处没有服务进程在等待连接时,远程机器的 TCP 协议将发送一个 RST 数据段,向客户机报告这个错误。客户机的 TCP 协议在接收到 RST 数据段后不再继续发送 SYN 数据段,函数立即以错误返回。
注:RST(reset)位:表示请求重置连接。当 TCP 协议接收到一个不能处理的数据段时,向对方 TCP 协议发送这种数据段,表示这个数据段所标识的连接出现了某种错误,请求 TCP 协议将这个连接清除。
有 3 种情况可能导致 TCP 协议发送 RST 数据段:
-
(1)SYN 数据段指定的目的端口处没有接收进程在等待;
-
(2)TCP 协议想放弃一个已经存在的连接;
-
(3)TCP 接收到一个数据段,但是这个数据段所标识的连接不存在。接收到 RST 数据段的 TCP 协议立即将这条连接非正常地断开,并向应用程序报告错误。
(3) 如果客户机的 SYN 数据段导致某个路由器产生 “目的地不可到达” 类型的 ICMP 消息,函数以错误返回,错误类型为 EHOSTUNREACH 或 ENETUNREACH。通常 TCP 协议在接收到这个 ICMP 消息之后,记录这个消息,然后继续几次发送 SYN 数据段,在所有的发送都告失败之后,TCP 协议检查这个 ICMP 消息,函数以错误返回。
注:ICMP:Internet 消息控制协议。Internet 的运行主要是由 Internet 的路由器来控制,路由器完成 IP 数据包的发送和接收,如果发送数据包时发生错误,路由器使用 ICMP 协议来报告这些错误。ICMP 数据包是封装在 IP 数据包的数据部分中进行传输的,其格式如下:
ICMP 数据包主要有以下类型:
(1) 目的地不可到达:A、目的主机未运行;B、目的地址不存在;C、路由表中没有目的地址对应的条目,因而路由器无法找到去往目的主机的路由。
(2) 超时:路由器将接收到的 IP 数据包的生存时间(TTL)域减 1,如果这个域的值变为 0,路由器丢弃这个 IP 数据包,并且发送这种 ICMP 消息。
(3) 参数出错:当 IP 数据包中有无效域时发送。
(4) 重定向:将一条新的路径通知主机。
(5) ECHO 请求、ECHO 回答:这两条消息用语测试目的主机是否可以到达。请求者向目的主机发送 ECHO 请求 ICMP 数据包,目的主机在接收到这个 ICMP 数据包之后,返回 ECHO 回答 ICMP 数据包。
(6) 时戳请求、时戳回答:ICMP 协议使用这两种消息从其他机器处获得其时钟的当前时间。
调用函数 connect 的过程中,当客户机 TCP 协议发送了 SYN 数据段的确认之后,TCP 状态由 CLOSED 状态转为 SYN_SENT 状态,在接收到对 SYN 数据段的确认之后,TCP 状态转换成 ESTABLISHED 状态,函数成功返回。如果调用函数 connect 失败,应该用 close 关闭这个套接字描述符,不能再次使用这个套接字描述符来调用函数 connect。
connect 函数的出错处理:
(1)ETIMEOUT-connection timed out 目的主机不存在,没有返回任何相应,例如主机关闭
(2)ECONNREFUSED-connection refused(硬错)到达目的主机后,由于各种原因建立不了连接,主机返回 RST(复位)响应,例如主机监听进程未启用,tcp 取消连接等
(3)EHOSTTUNREACH-no route to host(软错) 路由上引发了一个目的地不可达的 ICMP 错误
其中(1)(3),客户端会进行定时多次重试,一定次数后才返回错误。另外,当 connect 连接失败时,sockfd 套接口不可用,必须关闭后重新 socket 分配才行。
via:
-
TCP 的状态:SYN, FIN, ACK, PSH, RST, URG 简介及 ACK 确认机制_psh ack-CSDN 博客
https://blog.csdn.net/llzhang_fly/article/details/108676070 -
TCP 的连接状态标识(SYN, FIN, ACK, PSH, RST, URG)_fin ack-CSDN 博客
https://blog.csdn.net/m0_37989944/article/details/120086446
相关文章:
TCP 连接状态标识 | SYN, FIN, ACK, PSH, RST, URG
注:本文为“TCP 连接状态标识”相关文章合辑。 TCP 的状态:SYN, FIN, ACK, PSH, RST, URG 简介及 ACK 确认机制 llzhang_fly 于 2020-09-19 05:25:26 发布 1、TCP 的状态 FLAGS 字段状态 在 TCP 层,有个 FLAGS 字段,这个字段有…...
OSPF的LSA的学习研究
OSPF常见1、2、3、4、5、7类LSA的研究 1、拓扑如图,按照地址表配置,激活OSPF划分相关区域并宣告相关网段 2、1类LSA,每台运行了OSPF的路由器都会产生,描述了路由器的直连接口状况和cost 可以看到R1产生了一条router lsa࿰…...
C# OpenCV机器视觉:转速测量
在一个看似平常却又暗藏神秘能量的日子里,阿杰正在他那充满科技感的实验室里,对着一堆奇奇怪怪的仪器发呆。突然,手机铃声如一道凌厉的剑气划破寂静,原来是工厂的赵厂长打来的紧急电话:“阿杰啊,咱们工厂新…...
wireshark 网络分析工具
✍作者:柒烨带你飞 💪格言:生活的情况越艰难,我越感到自己更坚强;我这个人走得很慢,但我从不后退。 📜系列专栏:网络安全从菜鸟到飞鸟的逆袭 目录 一、网络截获数据包的基础1、以太网…...
XXL-JOB 加入 GitCode:推动分布式任务调度进阶发展
在当今企业数字化转型加速的时代背景下,任务调度在保障系统高效运行方面的关键作用日益凸显。XXL-JOB 正式加入 GitCode,成为 G-Star 优秀毕业项目,为分布式任务调度领域带来了新的契机与活力,助力企业应对复杂多变的业务需求。 X…...
Java Web开发进阶——WebSocket与实时通信
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,广泛应用于需要实时数据交换的应用程序中。它能够实现服务器与客户端之间的双向通信,避免了传统 HTTP 请求/响应的延迟。结合 Spring Boot,开发实时通信应用变得更加高效与简便。 1. …...
解决“无法定位程序输入点 av_buffer_create 于动态链接库 XXX\Obsidian.exe 上”问题
解决“无法定位程序输入点 av_buffer_create 于动态链接库 XXX\Obsidian.exe 上”问题 问题描述 本人在使用zotero中的zotero one(青柠学术插件)的时候,使用插件跳转obsidian中的对应笔记,出现上图情况。(错误中提到的…...
晨辉面试抽签和评分管理系统之十:如何搭建自己的数据库服务器,使用本软件的网络版
晨辉面试抽签和评分管理系统(下载地址:www.chenhuisoft.cn)是公务员招录面试、教师资格考试面试、企业招录面试等各类面试通用的考生编排、考生入场抽签、候考室倒计时管理、面试考官抽签、面试评分记录和成绩核算的面试全流程信息化管理软件。提供了考生…...
分布式数据存储基础与HDFS操作实践(副本)
以下为作者本人撰写的报告,步骤略有繁琐,不建议作为参考内容,可以适当浏览,进一步理解。 一、实验目的 1、理解分布式文件系统的基本概念和工作原理。 2、掌握Hadoop分布式文件系统(HDFS)的基本操作。 …...
Rust:指针 `*T` 和引用 `T`的区别
在 Rust 编程语言中,*T 和 &T 是两种不同类型的指针,它们各自代表了不同的内存访问方式和所有权模型。 *T(原始指针或裸指针): *T 是一个原始指针(也称为裸指针或裸引用),它可以…...
【2025最新版】PCL点云处理算法汇总(C++长期更新版)
博客长期更新,最近一次更新时间为:2025年1月17日。 pcl::copyPointCloud(*cloud, indicesY, *cloud_yboundary);目录 配库常用数据免费下载链接一、点云滤波1、常用滤波器2、采样滤波3、裁剪滤波 二、KD树与八叉树1、KD树2、八叉树 三、点云配准粗配准精…...
换了城市ip属地会变吗?为什么换了城市IP属地不变
当我们跨越城市的界限,从一个地方迁移到另一个地方时,许多日常使用的网络服务和应用程序都会感知到这种变化,其中一个显著的现象就是IP属地的变化。IP属地,即IP地址所在的地理位置信息,它通常与互联网服务提供商&#…...
mysql 如何快速删除表数据
在数据库管理中, 经常会遇到需要删除大量数据的情况. 对于 MySQL 数据库而言, 如何高效快速地删除数据是一个值得深入探讨的问题. 本文将详细介绍几种在 MySQL 中快速删除数据的方法及相关注意事项. delete 语句 delete 语句可以删除符合条件的指定数据, 但是在删除大量数据…...
Windows安装Jenkins——及修改主目录、配置简体中文、修改插件源
一、简介 Jenkinshttps://www.jenkins.io/zh/ Jenkins是开源CI&CD软件领导者, 提供超过1000个插件来支持构建、部署、自动化, 满足任何项目的需要。 二、Windows安装配置Jenkins2.479 2.1、J...
【机器学习:二十二、机器学习项目开发的技巧】
机器学习项目开发的技巧 机器学习项目的开发不仅仅依赖于算法的选择和模型的调优,还需要良好的项目管理技巧和方法论。以下是机器学习项目开发中的关键技巧: 明确需求:在项目启动之前,明确问题定义和业务目标。例如,…...
用python实战excel和word自动化
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 python实现excel和word自动化--批量处理 前言--需求快要期末了需要,提交一个年级的学生成绩数据,也就是几百份。当前我们收集了一份excel表格…...
Conda的一些常用命令
以下是Conda的一些常用命令: pip freeze > requirements.txt pip install -r requirements.txt 基本信息查看类 查看conda版本: conda -V 或 conda --version 可以查看当前安装的conda版本。 查看conda帮助信息: conda -h 或 conda --he…...
ESP8266 AP模式 网页配网 arduino ide
ESP8266的AP配网,可以自行配置网络,一个简单的demo,文档最后有所有的代码,已经测试通过. 查看SPIFFS文件管理系统中的文件 账号密码是否存在,如不存在进入AP配网,如存在进入wifi连接模式 // 检查Wi-Fi凭据if (isWiFiConfigured()) {Serial.println("找到Wi-Fi凭据&#…...
《AI与鸿蒙Next:建筑设计可视化的革新力量》
在建筑设计领域,可视化对于呈现设计理念、与客户沟通以及指导施工等环节都至关重要。人工智能与鸿蒙Next图形渲染技术的发展,为建筑设计可视化带来了前所未有的变革与机遇。 人工智能在建筑设计可视化中的作用 快速生成设计方案:人工智能可以…...
Edge Scdn是什么,它如何提升网站安全性与访问速度?
随着网络攻击的日益猖獗,尤其是分布式拒绝服务(DDoS)攻击的频繁发生,如何保护网站的安全性并确保用户的访问体验变得极为重要。Edge Scdn(内容分发网络)作为一种新兴的技术方案,逐渐被越来越多的…...
[Collection与数据结构] PriorityQueue与堆
1. 优先级队列 1.1 概念 前面介绍过队列,队列是一种先进先出(FIFO)的数据结构,但有些情况下,操作的数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列,该中场景下,使用队列显然…...
C#调用OpenCvSharp实现图像的开运算和闭运算
对图像同时进行腐蚀和膨胀操作,顺序不同则效果也不同。先腐蚀后膨胀为开运算,能够消除小斑点和细小的突出物、平滑图像以及改善边缘;先膨胀后腐蚀为闭运算,能够去除噪点、填补图像孔洞、连接邻近物体和平滑物体边界。 OpenCvS…...
okhttp断点续传
使用 OkHttp 实现断点续传,关键是通过设置 Range 请求头向服务器请求文件的部分内容。下面是详细的实现步骤和示例代码。 步骤 获取文件的总大小:在开始下载前,通常需要知道文件的总大小,可以通过发送一个初始请求来获取。记录已…...
异步 HTTP 请求
fetch 是一个用于进行异步 HTTP 请求的 JavaScript API。 fetch 基本用法 // 使用 fetch 进行 GET 请求 fetch(https://api.example.com/data).then(response > {// 检查响应是否成功if (!response.ok) {throw new Error(Network response was not ok);}// 解析响应数据为…...
仿射密码实验——Python实现(完整解析版)
文章目录 前言实验内容实验操作步骤1.编写主程序2.编写加密模块3.编写解密模块4.编写文件加解密模块 实验结果实验心得实验源码scirpt.pyusefile.py 前言 实验目的 1)初步了解古典密码 2)掌握仿射密码的实现 实验方法 根据下图仿射密码(变换…...
Ubuntu安装K8S
第一步: 安装docker Install Docker #注意docker是早期的名称已经过时了,因此请使用如下命令,一步到位安装docker-ce。 第二步:设置K8S源: (大陆使用aliyun源,大陆外使用google源)…...
C语言初阶习题【29】杨氏矩阵
1. 题目描述——杨氏矩阵 有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。 要求:时间复杂度小于O(N); 2. 思路 3. 代码实现1 #include<stdio.h>void fin…...
(01)FreeRTOS移植到STM32
一、以STM32的裸机工程模板 任意模板即可 二、去官网上下载FreeRTOS V9.0.0 源码 在移植之前,我们首先要获取到 FreeRTOS 的官方的源码包。这里我们提供两个下载 链 接 , 一 个 是 官 网 : http://www.freertos.org/ , 另…...
从AI生成内容到虚拟现实:娱乐体验的新边界
引言 在快速发展的科技时代,娱乐行业正经历一场前所未有的变革。传统的娱乐方式正与先进技术融合,创造出全新的沉浸式体验。从AI生成的个性化内容,到虚拟现实带来的身临其境的互动场景,科技不仅改变了我们消费娱乐的方式…...
买入的股票
银行12 工商,建设,农业,中国,招商,交通,邮储,中信,兴业,浦发,平安,光大 保险4:人寿,平安,太平洋,…...
Springboot Redisson 分布式锁、缓存、消息队列、布隆过滤器
redisson-spring-boot-starter 是 Redisson 提供的 Spring Boot 集成包,旨在简化与 Redis 的交互,包括分布式锁、缓存、消息队列、布隆过滤器等功能的实现。 Maven 依赖 在 Spring Boot 项目中添加 redisson-spring-boot-starter 依赖: <…...
如何在 Rocky Linux 上安装极狐GitLab?
本文分享如何在 Rocky Linux 操作系统上安装极狐GitLab。 相关资料 极狐GitLab 在各种操作系统下的安装指南官网文档 前提条件 一个安装了 Rocky Linux 操作系统的云服务器 可以查看 /etc/os-release 中的信息,确认操作系统信息: NAME"Rocky …...
50.【8】BUUCTF WEB HardSql
进入靶场 随便输输 上order by ????????,被过滤了,继续找其他也被过滤的关键字 #,-- -,-- 都不行,尝试其他特殊字符后发现and,union,select,空格,都被过滤了 如下 我就不知…...
Shell的运行原理以及Linux中的权限问题
Shell的运行原理 Linux严格意义上说的是一个操作系统,我们称之为“核心(kernel)“ ,但我们一般用户,不能直接使用kernel。 而是通过kernel的“外壳”程序,也就是所谓的shell,来与kernel沟通。如…...
Maven在Win10上的安装教程
诸神缄默不语-个人CSDN博文目录 这个文件可以跟我要,也可以从官网下载: 第一步:解压文件 第二步:设置环境变量 在系统变量处点击新建,输入变量名MAVEN_HOME,变量值为解压路径: 在系统变…...
服务器数据恢复—EMC存储POOL中数据卷被删除的数据恢复案例
服务器数据恢复环境&故障: EMC Unity 400存储连接了2台硬盘柜。2台硬盘柜上一共有21块硬盘(520字节)。21块盘组建了2组RAID6:一组有11块硬盘,一组有10块硬盘。 在存储运行过程中,管理员误操作删除了 2组…...
Go语言之路————func
Go语言之路————func 前言1.最基本的方法定义2.方法中参数的传递3.方法中的返回值4.匿名方法5.闭包的概念6.defer关键词 前言 我是一名多年Java开发人员,因为工作需要现在要学习go语言,Go语言之路是一个系列,记录着我从0开始接触Go&#…...
基于 Electron 应用的安全测试基础 — 提取和分析 .asar 文件
视频教程在我主页简介或专栏里 目录: 提取和分析 .asar 文件 4.1. .asar 文件提取工具 4.1.1. 为什么选择 NPX? 4.2. 提取过程 4.3. 提取 .asar 文件的重要性 4.3.1 关键词 4.3.2 执行关键词搜索 4.3.2.1 使用命令行工具“grep”进行关键词搜索 4.3.2…...
微软与腾讯技术交锋,TRELLIS引领3D生成领域多格式支持新方向
去年 11 月,腾讯推出 Hunyuan3D 生成模型,是业界首个同时支持文字和图像生成 3D 的开源大模型。紧接着不到一个月,微软便发布了全新框架 TRELLIS,加入 3D 资产生成领域的竞争中。TRELLIS 支持多格式输出,包括辐射场、3…...
ubuntu18.04开发环境下samba服务器的搭建
嵌入式linux的发展很快,最近准备在一个新项目上采用新一代的linux核心板,发现linux内核的版本已经更新到5.4以上甚至6.0以上;之前常用的linux内核版本是2.6.4,虽然在某些项目上还能用但是明显跟不上时代的步伐了,所以要…...
LabVIEW实现油浸式变压器自主监测与实时报告
油浸式变压器广泛应用于电力系统中,尤其是在电力传输和分配领域。为了确保变压器的安全、稳定运行,及时监测其工作状态至关重要。传统的变压器监测方法通常依赖人工巡检和定期检查,但这不能及时发现潜在的故障隐患,且效率较低。随…...
21_Spring Boot缓存注解介绍
前面我们通过使用@EnableCaching、@Cacheable注解实现了Spring Boot默认的基于注解的缓存管理,除此之外,还有更多的缓存注解以及注解属性可以配置优化缓存管理。下面我们针对Spring Boot中的缓存注解及相关属性进行详细讲解。 1.@EnableCaching注解 @EnableCaching是由Spri…...
Linux和Docker常用终端命令:保姆级图文详解
文章目录 前言1、Docker 常用命令1.1、镜像管理1.2、容器管理1.3、网络管理1.4、数据卷管理1.5、监控和性能管理 2、Linux 常用命令分类2.1、文件和目录管理2.2、用户管理2.3、系统监控和性能2.4、软件包管理2.5、网络管理 前言 亲爱的家人们,创作很不容易…...
【WRF理论第九期】输出文件:wrfout 和 wrfrst
【WRF理论第九期】输出文件:wrfout 和 wrfrst 1. wrfout 文件wrfout 文件读取(Python)2. wrfrst 文件参考在 WRF(Weather Research and Forecasting)模型中,wrfout 和 wrfrst 是两种重要的输出文件,分别代表不同类型的模拟结果和功能。 1. wrfout 文件 wrfout 文件是 …...
学习threejs,使用OrbitControls相机控制器
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.OrbitControls 相机控…...
CryptoMamba:利用状态空间模型实现精确的比特币价格预测
“CryptoMamba: Leveraging State Space Models for Accurate Bitcoin Price Prediction” 论文地址:https://arxiv.org/pdf/2501.01010 Github地址:https://github.com/MShahabSepehri/CryptoMamba 摘要 预测比特币价格由于市场的高波动性和复杂的非线…...
RocketMQ 知识速览
文章目录 一、消息队列对比二、RocketMQ 基础1. 消息模型2. 技术架构3. 消息类型4. 消费者类型5. 消费者分组和生产者分组 三、RocketMQ 高级1. 如何解决顺序消费和重复消费2. 如何实现分布式事务3. 如何解决消息堆积问题4. 如何保证高性能读写5. 刷盘机制 (topic 模…...
uniapp button 去除边框
在找去除边框的办法时试了好久 css里设置了 border: none; /* 去掉边框 */outline: none; /* 确保点击时不出现轮廓 */压根不行,按钮还是浮在页面上有明显轮廓 最后看到了大佬的文章 https://www.cnblogs.com/menxiaojin/p/13752916.html button::after{border: no…...
基于mybatis、bootstarp、的maven新人练手学生管理studentManage项目
分析:如果能注册并且登录,那每个人都是管理员,任何人都可以对数据恶意操作,这样数据极其不安全。为了数据的安全考虑, 要么创建学生注册页面,但是主页面只能显示本人信息,不能对其他人进行操作&…...
Visual Studio Community 2022(VS2022)安装方法
废话不多说直接上图: 直接上步骤: 1,首先可以下载安装一个Visual Studio安装器,叫做Visual Studio installer。这个安装文件很小,很快就安装完成了。 2,打开Visual Studio installer 小软件 3,…...