简体   繁体   English

ss 命令显示 TIME_WAIT 而不是逻辑上不适合的 CLOSE_WAIT

[英]ss command shows TIME_WAIT instead of CLOSE_WAIT which does not fit logically

I am trying to understand TIME_WAIT and CLOSE_WAIT.我正在尝试了解 TIME_WAIT 和 CLOSE_WAIT。

I have opened a socket connection via Chrome console, which connects to my Java WebSocket server running locally - then closed it:我通过 Chrome 控制台打开了一个套接字连接,该连接连接到我在本地运行的 Java WebSocket 服务器 - 然后将其关闭:

var webSocket = new WebSocket('ws://127.0.0.1:1234/support');
webSocket.close();

What I expect to see when I run sudo ss -apn|grep ':1234' is CLOSE_WAIT as it the client who has closed the connection, and should be first to send fin packet, which would have changed server socket status to CLOSE_WAIT, however, I see differently.当我运行sudo ss -apn|grep ':1234'时,我期望看到的是 CLOSE_WAIT,因为它是关闭连接的客户端,并且应该首先发送 fin 数据包,这会将服务器套接字状态更改为 CLOSE_WAIT,但是,我的看法不同。

Tuesday 17 May 2022 06:23:21 PM IST

tcp6       0      0 :::1234                 :::*                    LISTEN      86008/java          
tcp6       0      0 127.0.0.1:1234          127.0.0.1:60672         TIME_WAIT   -   

Can somebody please explain what is happening?有人可以解释发生了什么吗?

Update 1:更新1:

masood@masood-ThinkPad-L450:~/Desktop/code/current/chat_server11$ sudo tcpdump -i lo port 1234
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes



21:39:58.376375 IP6 ip6-localhost.34196 > ip6-localhost.1234: Flags [S], seq 969747395, win 65476, options [mss 65476,sackOK,TS val 3310041060 ecr 0,nop,wscale 7], length 0
21:39:58.376393 IP6 ip6-localhost.1234 > ip6-localhost.34196: Flags [S.], seq 630365028, ack 969747396, win 65464, options [mss 65476,sackOK,TS val 3310041060 ecr 3310041060,nop,wscale 7], length 0
21:39:58.376410 IP6 ip6-localhost.34196 > ip6-localhost.1234: Flags [.], ack 1, win 512, options [nop,nop,TS val 3310041060 ecr 3310041060], length 0
21:39:58.378183 IP6 ip6-localhost.34196 > ip6-localhost.1234: Flags [P.], seq 1:535, ack 1, win 512, options [nop,nop,TS val 3310041062 ecr 3310041060], length 534
21:39:58.378197 IP6 ip6-localhost.1234 > ip6-localhost.34196: Flags [.], ack 535, win 508, options [nop,nop,TS val 3310041062 ecr 3310041062], length 0
21:39:58.398870 IP6 ip6-localhost.1234 > ip6-localhost.34196: Flags [P.], seq 1:130, ack 535, win 512, options [nop,nop,TS val 3310041083 ecr 3310041062], length 129
21:39:58.398890 IP6 ip6-localhost.34196 > ip6-localhost.1234: Flags [.], ack 130, win 511, options [nop,nop,TS val 3310041083 ecr 3310041083], length 0





21:40:08.678597 IP6 ip6-localhost.34196 > ip6-localhost.1234: Flags [P.], seq 535:541, ack 130, win 512, options [nop,nop,TS val 3310051362 ecr 3310041083], length 6
21:40:08.678618 IP6 ip6-localhost.1234 > ip6-localhost.34196: Flags [.], ack 541, win 512, options [nop,nop,TS val 3310051362 ecr 3310051362], length 0
21:40:08.679275 IP6 ip6-localhost.1234 > ip6-localhost.34196: Flags [P.], seq 130:132, ack 541, win 512, options [nop,nop,TS val 3310051363 ecr 3310051362], length 2
21:40:08.679293 IP6 ip6-localhost.34196 > ip6-localhost.1234: Flags [.], ack 132, win 512, options [nop,nop,TS val 3310051363 ecr 3310051363], length 0
21:40:08.679438 IP6 ip6-localhost.1234 > ip6-localhost.34196: Flags [F.], seq 132, ack 541, win 512, options [nop,nop,TS val 3310051363 ecr 3310051363], length 0
21:40:08.679487 IP6 ip6-localhost.34196 > ip6-localhost.1234: Flags [F.], seq 541, ack 133, win 512, options [nop,nop,TS val 3310051363 ecr 3310051363], length 0
21:40:08.679506 IP6 ip6-localhost.1234 > ip6-localhost.34196: Flags [.], ack 542, win 512, options [nop,nop,TS val 3310051363 ecr 3310051363], length 0

I tried to capture packets using tcpdump and I can clearly see that server is sending directly FIN+ACK without receiving FIN .I am totally confused.我尝试使用tcpdump捕获数据包,我可以清楚地看到服务器直接发送FIN+ACK而没有收到FIN 。我完全糊涂了。

as it the client who has closed the connection, and should be first to send fin packet因为它是关闭连接的客户端,应该首先发送fin数据包

That is an incorrect assumption.这是一个不正确的假设。 When the client calls close() on a fully established WebSocket connection, close() will perform a handshake that causes the server to close the TCP connection first (send the initial FIN ), rather than the client.当客户端在完全建立的 WebSocket 连接上调用close()时, close()将执行握手,导致服务器首先关闭 TCP 连接(发送初始FIN ),而不是客户端。

This is described in the WebSocket protocol spec, RFC 6455 , Section 7 , "Closing the Connection":这在 WebSocket 协议规范RFC 6455第 7 节“关闭连接”中有描述:

7.1.1. 7.1.1. Close the WebSocket Connection关闭 WebSocket 连接

To Close the WebSocket Connection , an endpoint closes the underlying TCP connection.关闭 WebSocket 连接,端点会关闭底层 TCP 连接。 An endpoint SHOULD use a method that cleanly closes the TCP connection, as well as the TLS session, if applicable, discarding any trailing bytes that may have been received.端点应该使用干净关闭 TCP 连接以及 TLS 会话(如果适用)的方法,丢弃可能已接收到的任何尾随字节。 An endpoint MAY close the connection via any means available when necessary, such as when under attack.端点可以在必要时通过任何可用的方式关闭连接,例如在受到攻击时。

The underlying TCP connection, in most normal cases, SHOULD be closed first by the server, so that it holds the TIME_WAIT state and not the client (as this would prevent it from re-opening the connection for 2 maximum segment lifetimes (2MSL), while there is no corresponding server impact as a TIME_WAIT connection is immediately reopened upon a new SYN with a higher seq number).在大多数正常情况下,底层 TCP 连接应该首先由服务器关闭,以便它保持 TIME_WAIT 状态而不是客户端(因为这将阻止它在 2 个最大段生命周期 (2MSL) 内重新打开连接,而没有相应的服务器影响,因为 TIME_WAIT 连接会在具有更高 seq 号的新 SYN 时立即重新打开)。 In abnormal cases (such as not having received a TCP Close from the server after a reasonable amount of time) a client MAY initiate the TCP Close.在异常情况下(例如在合理的时间后没有从服务器收到 TCP 关闭)客户端可以发起 TCP 关闭。 As such, when a server is instructed to Close the WebSocket Connection it SHOULD initiate a TCP Close immediately, and when a client is instructed to do the same, it SHOULD wait for a TCP Close from the server.因此,当服务器被指示关闭 WebSocket 连接时,它应该立即启动 TCP 关闭,并且当客户端被指示执行相同操作时,它应该等待来自服务器的 TCP 关闭。

As an example of how to obtain a clean closure in C using Berkeley sockets, one would call shutdown() with SHUT_WR on the socket, call recv() until obtaining a return value of 0 indicating that the peer has also performed an orderly shutdown, and finally call close() on the socket.作为如何使用 Berkeley 套接字在 C 中获得干净闭包的示例,可以在套接字上调用带有 SHUT_WR 的 shutdown(),调用 recv() 直到获得返回值 0,表明对等方也执行了有序关闭,最后在套接字上调用 close() 。

7.1.2. 7.1.2. Start the WebSocket Closing Handshake启动 WebSocket 关闭握手

To Start the WebSocket Closing Handshake with a status code (Section 7.4) /code/ and an optional close reason (Section 7.1.6) /reason/, an endpoint MUST send a Close control frame , as described in Section 5.5.1, whose status code is set to /code/ and whose close reason is set to /reason/.要使用状态码(第 7.4 节)/code/ 和可选的关闭原因(第 7.1.6 节)/reason/启动 WebSocket 关闭握手端点必须发送一个关闭控制帧,如第 5.5.1 节所述,其状态码设置为 /code/,关闭原因设置为 /reason/。 Once an endpoint has both sent and received a Close control frame, that endpoint SHOULD Close the WebSocket Connection as defined in Section 7.1.1.一旦一个端点发送和接收了一个关闭控制帧,该端点应该关闭第 7.1.1 节中定义的 WebSocket 连接

As well as the WebSockets standard , close() method :以及WebSockets 标准close()方法

  1. Run the first matching steps from the following list:运行以下列表中的第一个匹配步骤:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM