let’s terminate the server by press q at client side
1 2 3 4 5 6 7 8 9 10
=> ./ehclient 127.0.0.1 19999 Connected......... Input message(Q to quit): hello Mesage from server: Input message(Q to quit): asdka Mesage from server: @ Input message(Q to quit): alksdflaskd;afs Mesage from server: Input message(Q to quit): q
before terminate the server, we need firstly gurantee the connection between client and server established as shown prevously, then I press ctrl+c to terminate the server here is the connection status change
I just saw FIN_WAIT_2 for server and CLOSE_WAIT for client. looks like client not sending FIN to server, so server keeps staying in FIN_WAIT_2
if we observe closely, we will see CLOSE_WAIT is for client - ehclient, the server side is already terminated, so the connection status is not presented. time-wait vs close-wait%20has%20closed%20the%20connection.)
CLOSE_WAIT indicates that the remote endpoint (other side of the connection) has closed the connection. TIME_WAIT indicates that local endpoint (this side) has closed the connection. during the close-wait period, if you try to restart server, you would see error
reference at above pic, host 1 is like our server, host 2 is client.
ctrl+c , the server would send a fin to client, its own status changes to FIN_WAIT_1
client recieve message, when it sees fin, it ACK server immedialtly and change status from ESTABLISHED to CLOSE_WAIT
after getting ack from client, serve knows client already got its fin message, so it changes FIN_WAIT_1 to FIN_WAIT_2
the client still not able to close connection now, because its reading or writing buffer may still has remaining contents it needs to process. when client read EOF in buffer, then it knows server side it ready to close so it send FIN to server, and change its status from CLOSE_WAIT to LAST_ACK
when server got the FIN, it would ACK to client, and changes its status from FIN_WAIT_2 to TIME_WAIT. when client get it, then client would close the connection.
the server would wait for 2 MSL(maximum segment lifetime), after that, its status changes from TIME_WAIT to closed
why we nees step 6? because at step 5, server would send ACK to client, if server closed connection immediately but client misses this message, then client would never recieves ACK again , it would keep sending FIN to server and expect ACK. so we give a time_wait for buffering, the server side would keep sending ACK to client until time-wait passed 2 MSL.
summary
no matter client or server side, the side who initialize the FIN, ie, attempt to close connection would experience the TIME_WAIT status.
the counterpart side would experiences CLOSE_WAIT status
if client intialize connection close, then client would have TIME_WAIT and server side would have CLOSE_WAIT, ie,if we see a lot of CLOSE_WAIT on remote server, we should know the server side doesn’t give FIN to client, so the server side code must have something wrong.
if server initialize connection close operation, and we see a lot TIME_WAIT, it might because the client doesn’t get ACK from server, or server doesn’t send ACK to client, then client resend FIN to server, so server reset the TIME_WAIT timer.