端口状态“LISTENING”、“TIME_WAIT”、“CLOSE_WAIT”和“ESTABLISHED”有什么区别?

端口状态“LISTENING”、“TIME_WAIT”、“CLOSE_WAIT”和“ESTABLISHED”有什么区别?

我用来netstat检查我的端口状态。

LISTENING我想知道端口状态、TIME_WAITCLOSE_WAIT和之间有什么区别FIN_WAIT1ESTABLISHED

答案1

手册页netstat每个状态都有简短的描述:

   ESTABLISHED
          The socket has an established connection.
   SYN_SENT
          The socket is actively attempting to establish a connection.
   SYN_RECV
          A connection request has been received from the network.
   FIN_WAIT1
          The socket is closed, and the connection is shutting down.
   FIN_WAIT2
          Connection is closed, and the socket is waiting for  a  shutdown
          from the remote end.
   TIME_WAIT
          The socket is waiting after close to handle packets still in the
          network.
   CLOSE  The socket is not being used.
   CLOSE_WAIT
          The remote end has shut down, waiting for the socket to close.
   LAST_ACK
          The remote end has shut down, and the socket is closed.  Waiting
          for acknowledgement.
   LISTEN The  socket is listening for incoming connections.  Such sockets
          are  not  included  in  the  output  unless  you   specify   the
          --listening (-l) or --all (-a) option.
   CLOSING
          Both  sockets are shut down but we still don't have all our data
          sent.
   UNKNOWN
          The state of the socket is unknown.

您可以使用状态转换图(示例这里这里这里) 来更好地理解各州。


假设有两个程序尝试建立套接字连接(分别称为a和)。两个程序b都设置套接字并转换到状态。然后一个程序(例如)尝试连接到另一个程序()。发送请求并进入状态,并接收请求并进入状态。当确认请求时,它们进入状态并执行其任务。现在可能会发生以下几件事:LISTENabaSYN_SENTbSYN_RECVbESTABLISHED

  1. a希望关闭连接,并输入FIN_WAIT1b接收FIN请求,发送一个ACK(然后a输入FIN_WAIT2),输入CLOSE_WAIT,告知a它正在关闭,然后输入LAST_ACK。一旦a确认这一点(并输入TIME_WAIT),b输入CLOSEa等待一会儿以查看是否还有剩余,然后输入CLOSE
  2. ab已完成其工作并决定关闭连接(同时关闭)。当a处于 时,它不会收到来自 的消息,FIN_WAIT而是收到(因为希望也关闭它),进入。但仍然有一些消息要发送(应该为其原始 获得的),一旦到达,就会照常进入。ACKbFINbaCLOSINGACKaFINACKaTIME_WAIT

答案2

监听:服务端调用os的listen()系统调用“等待”一个TCP连接。但是这个系统调用不会阻塞服务端,服务端会继续调用accept(),当读取到一个空队列时会阻塞服务端。服务端调用listen()之后,os会经过TCP三次握手协议,把一个预计的连接放入队列中。此时服务端会从accept()中醒来,并为该连接获取一个新的socket文件描述符。你可以使用新的socket fd从os队列中读取。此时你的netstate变成“ESTABLISHED”

相关内容