private void close(@Nullable final StreamError error, final boolean networkInterruption, final boolean force) {
        if (state.compareAndSet(State.OPEN, State.CLOSED)) {
            
            if (session != null) {
                if (!force && !networkInterruption) {
                    // A 'clean' closure should never be resumed (see #onRemoteDisconnect for handling of unclean disconnects). OF-2752
                    session.getStreamManager().formalClose();
                }
                session.setStatus(Session.Status.CLOSED);
            }

            if (!force) {
                boolean allowedToWrite = false;
                try {
                    requestWriting();
                    allowedToWrite = true;
                    // Register that we started sending data on the connection
                    writeStarted();

                    String rawEndStream = "";
                    if (error != null) {
                        rawEndStream = error.toXML();
                    }
                    rawEndStream += "</stream:stream>";

                    writer.write(rawEndStream);
                    writer.flush();
                }
                catch (Exception e) {
                    Log.debug("Failed to deliver stream close tag: " + e.getMessage());
                }
                
                // Register that we finished sending data on the connection
                writeFinished();
                if (allowedToWrite) {
                    releaseWriting();
                }
            }
                
            closeConnection();

            notifyCloseListeners().whenComplete((v,t) -> {
                closeListeners.clear();
                if (t != null) {
                    Log.warn("Exception while invoking close listeners for {}", this, t);
                }
            });
        }
    }
Normal connection close will attempt to write the stream end tag. Otherwise this method
forces the connection closed immediately. This method will be called when  we need to close the socket, discard
the connection and its session.
xmppserver/src/main/java/org/jivesoftware/openfire/net/SocketConnection.java