go开发需要了解的net 连接关闭 - yellia1989/learn-doc GitHub Wiki

1、连接关闭 TCPConn提供了3个连接关闭的方法

  • Close 关闭读写
  • CloseRead 关闭读,对应shutdown(RD),丢弃socket os recv buf, 之后受到的包也在确认后丢弃
  • CloseWrite 关闭写,对应shutdown(WR),发送完socket os send buf后,走socket关闭逻辑

2、连接关闭后对读写的影响
例子中为了测试客户端和服务器的读写操作使用了sleep,这样可以严格控制读写次序,客户端每次向服务器发送svr hello,服务器每次向客户端发送client hello 例子代码

socket操作 具体步骤 客户端服务器读写返回值和socket状态
正常,服务器和客户端没有关闭读写
  1. 服务器开启listen
  2. 客户端connect
  3. 客户端2秒后开始读写,每2秒读写一次
  4. 服务器10秒后开始读写,每2秒读写一次
  1. 2秒后客户端后读阻塞,写成功,os socket send buf为0
  2. 10秒前服务器os socket recv buf有堆积,数量和客户端发送一直,证明客户端发送成功
  3. 10秒后服务器开始写,os socket send buf为0,客户端读成功
客户端关闭读
  1. 服务器开启listen
  2. 客户端connect
  3. 客户端调用CloseRead
  4. 客户端2秒后开始读写,每2秒读写一次
  5. 服务器10秒后开始读写,每2秒读写一次
  1. 2秒后客户端read立即返回EOF
  2. 2秒后客户端写成功,客户端os socket send buf=0,服务器os socket recv buf!=0
  3. 10秒后服务器write返回正常,服务器的os socket send buf=0,客户端的os socket recv buf=0,说明服务器发送数据成功,客户端收到的数据也在确认后被丢弃。
  4. 10秒后服务器read正常,也能接收到客户端发送的数据
  5. 客户端和服务器的socket状态为ESTABLISHED正常,并没有因为客户端调用了CloseRead而关闭
服务器关闭读
  1. 服务器开启listen
  2. 客户端connect
  3. 服务器在客户端连接成功后调用CloseRead
  4. 客户端2秒后开始读写,每2秒读写一次
  5. 服务器10秒后开始读写,每2秒读写一次
  1. 2秒后客户端read阻塞
  2. 2秒后客户端write返回正常,客户端的os socket send buf=0,服务器的os socket recv buf=0,说明客户端发送数据成功,服务器收到的数据也在确认后被丢弃。
  3. 10秒后服务器read EOF
  4. 10秒后服务器write正常,客户端也能正常读取
  5. 客户端和服务器的socket状态为ESTABLISHED正常,并没有因为服务端调用了CloseRead而关闭
客户端关闭写
  1. 服务器开启listen
  2. 客户端connect
  3. 客户端在客户端连接成功后调用CloseWrite
  4. 客户端2秒后开始读写,每2秒读写一次
  5. 服务器10秒后开始读写,每2秒读写一次
  1. 客户端调用CloseWrite后socket状态变为cli->svr FIN_WAIT_2 svr->cli CLOSE_WAIT
  2. 2秒后客户端阻塞在read
  3. 2秒后客户端写失败write: broken pipe
  4. 10秒后服务器读EOF
  5. 10庙后服务器写成功,客户端也能成功读
服务器关闭写
  1. 服务器开启listen
  2. 客户端connect
  3. 客户端2秒后开始读写,每2秒读写一次
  4. 服务器在客户端连接成功后调用CloseWrite
  5. 服务器10秒后开始读写,每2秒读写一次
  1. 服务器调用CloseWrite后socket状态变为cli->svr CLOSE_WAIT svr->cli FIN_WAIT_2
  2. 2秒后客户端读EOF
  3. 2秒后客户端写成功,客户端socket os send buf=0 服务器socket os recv buf != 0
  4. 10秒后服务器读成功
  5. 10庙后服务器失败write: broken pipe
客户端关闭读写
  1. 服务器开启listen
  2. 客户端connect
  3. 客户端在客户端连接成功后调用Close
  4. 客户端2秒后开始读写,每2秒读写一次
  5. 服务器10秒后开始读写,每2秒读写一次
  1. 客户端调用Close后socket状态变为cli->svr FIN_WAIT_2 svr->cli CLOSE_WAIT
  2. 2秒后客户端read: use of closed network connection
  3. 2秒后客户端write: use of closed network connection
  4. 10秒后服务器read EOF(读先发生)或RST(写先发生)
  5. 10秒后服务器write成功(因为客户端已经关闭了socket,会导致回复给服务器RST,服务器收到后关闭连接)
  6. 10秒后服务器write: broken pipe
服务器关闭读写
  1. 服务器开启listen
  2. 客户端connect
  3. 服务器在客户端连接成功后调用Close
  4. 客户端2秒后开始读写,每2秒读写一次
  5. 服务器10秒后开始读写,每2秒读写一次
  1. 客户端连接后服务器调用Close后socket状态变为cli->svr CLOSE_WAIT svr->cli FIN_WAIT_2
  2. 2秒后客户端read EOF(读先发生)或RST(写先发生)
  3. 2秒后客户端write成功(因为服务器已经关闭了socket,会导致回复给客户端RST,客户端收到后关闭连接)
  4. 10秒后服务器read EOF(读先发生)或RST(写先发生)
  5. 10秒后服务器read: use of closed network connection
  6. 10秒后服务器write: use of closed network connection
⚠️ **GitHub.com Fallback** ⚠️