code: func (cli *Client) Disconnect() error {
  	// Lock for the disconnection.
  	cli.muConn.Lock()
  
  	// Return an error if the Client has not yet connected to the Server.
  	if cli.conn == nil {
  		// Unlock.
  		cli.muConn.Unlock()
  
  		return ErrNotYetConnected
  	}
  
  	// Send a DISCONNECT Packet to the Server.
  	// Ignore the error returned by the send method because
  	// we proceed to the subsequent disconnecting processing
  	// even if the send method returns the error.
  	cli.send(packet.NewDISCONNECT())
  
  	// Close the Network Connection.
  	if err := cli.conn.Close(); err != nil {
  		// Unlock.
  		cli.muConn.Unlock()
  
  		return err
  	}
  
  	// Change the state of the Network Connection to disconnected.
  	cli.conn.disconnected = true
  
  	// Send the end signal to the goroutine via the channels.
  	select {
  	case cli.conn.sendEnd <- struct{}{}:
  	default:
  	}
  
  	// Unlock.
  	cli.muConn.Unlock()
  
  	// Wait until all goroutines end.
  	cli.conn.wg.Wait()
  
  	// Lock for cleaning the Network Connection.
  	cli.muConn.Lock()
  
  	// Lock for cleaning the Session.
  	cli.muSess.Lock()
  
  	// Clean the Network Connection and the Session.
  	cli.clean()
  
  	// Unlock.
  	cli.muSess.Unlock()
  
  	// Unlock.
  	cli.muConn.Unlock()
  
  	return nil
  }
docs: // Disconnect sends a DISCONNECT Packet to the Server and
  // closes the Network Connection.