7

I'm trying to get the following diagram on TikZ. However, I didn't find any package that is able to draw something similar. The most similar one I found was a sequence diagram using pgf-umlsd.

handshake

The following code is the best attempt to get the diagram. The problem is that I need the lines to be diagonals to show the delay in the connection.

How can I achieve this using TikZ?

\documentclass[tikz, border=2mm]{standalone}

\usetikzlibrary{arrows,shadows}
\usepackage{pgf-umlsd}

\begin{document}
    \begin{sequencediagram}
        \newthread[white]{c}{Initiator}
        \newinst[4]{s}{Receiver}

        \mess{c}{FIN}{s}
        \mess{s}{ACK}{c}
        \mess{s}{FIN}{c}
        \mess{c}{ACK}{s}

    \end{sequencediagram}

\end{document}

enter image description here

Similar questions

Network/Message Sequence Diagram poses the same problem, but the solution there is to use msc. However, I would like to get a TikZ solution (I think it looks nicer).

protocol message diagram - arrow colored has a similar solution using pgf-umlsd, but it has the same limitation of using only horizontal lines.

2 Answers 2

4

\mess command has an optional parameter which represent a delay (vertical separation) between tranmission and reception. You just need to use it:

\mess[1]{c}{FIN}{s}

An example using it and explanations about inserting comments and some other style changes can be found in Add bars and annotations when using pgf-umlsd

EDIT

Although John Kormylo has been faster than me. I also think that sometimes i'is easier to draw it by hand instead of using pgf-umlsd.

\documentclass[tikz, border=5mm]{standalone}

\usetikzlibrary{arrows,shadows,positioning}

\begin{document}

\begin{tikzpicture}[font=\sffamily,>=stealth',thick,
commentl/.style={text width=3cm, align=right},
commentr/.style={commentl, align=left},]
\node[] (init) {\LARGE Initiator};
\node[right=1cm of init] (recv) {\LARGE Receiver};


\draw[->] ([yshift=-1.7cm]init.south) coordinate (fin1o) -- ([yshift=-.7cm]fin1o-|recv) coordinate (fin1e) node[pos=.3, above, sloped] {FIN};

\draw[->] ([yshift=-.3cm]fin1e) coordinate (ack1o) -- ([yshift=-.7cm]ack1o-|init) coordinate (ack1e) node[pos=.3, above, sloped] {ACK};

\draw[->] (ack1e-|recv) coordinate (fin2o) -- ([yshift=-.7cm]fin2o-|init) coordinate (fin2e) node[pos=.3, above, sloped] {FIN};

\draw[->] ([yshift=-.3cm]fin2e) coordinate (ack2o) -- ([yshift=-.7cm]ack2o-|recv) coordinate (ack2e) node[pos=.3, above, sloped] {ACK};

\draw[thick, shorten >=-1cm] (init) -- (init|-ack2e);
\draw[thick, shorten >=-1cm] (recv) -- (recv|-ack2e);

\draw[dotted] (recv.285)--([yshift=2mm]recv.285|-fin1e) coordinate[pos=.5] (aux1);

\draw[dotted] (init.255)--([yshift=2mm]init.255|-fin1o);

\draw[dotted] ([yshift=1mm]init.255|-fin2e) --([yshift=-5mm]init.255|-ack2e) coordinate (aux2);

\node[commentr, right =2mm of ack2e] {\textbf{CLOSED}};
\node[commentr, right =2mm of fin2o] {\textbf{LAST ACK}};
\node[below left = 0mm and 2mm of init.south, commentl]{\textbf{ESTABLISHED}\\[-1.5mm]{\itshape connection}};
\node[left = 2mm of fin1o.west, commentl]{{\itshape active close}\\[-1mm]\textbf{FIN\_WAIT\_1}};
\node[left = 2mm of ack1e.west, commentl]{\textbf{FIN\_WAIT\_2}};
\node[below left = -1mm and 2mm of fin2e.west, commentl]{\textbf{TIME\_WAIT}};
\node[below left = -1mm and 2mm of aux2-|init, commentl]{\textbf{CLOSED}};

\node[right = 2mm of recv|-aux1, commentr]{\textbf{ESTABLISHED}\\[-1.5mm]{\itshape connection}};
\node[right = 2mm of fin1e.west, commentr]{\textbf{CLOSE\_WAIT}\\[-1mm]{\itshape passive close}};
\end{tikzpicture}

\end{document}

enter image description here

5

You can always do it the hard way. Using named coordinates makes it easier to change.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,arrows}

\begin{document}
\begin{center}
\begin{tikzpicture}[>=latex]
\coordinate (A) at (2,5);
\coordinate (B) at (2,0);
\coordinate (C) at (6,5);
\coordinate (D) at (6,0);
\draw[thick] (A)--(B) (C)--(D);
\draw (A) node[above]{\Large Initiator};
\draw (C) node[above]{\Large Receiver};

\coordinate (E) at ($(A)!.1!(B)$);
\draw (E) node[left]{\begin{tabular}{r}
\textit{active close}\\
\verb$FIN_WAIT_1$
\end{tabular}};

\coordinate (F) at ($(C)!.25!(D)$);
\draw (F) node[right]{\begin{tabular}{l}
\verb$CLOSE_WAIT$\\
\textit{passive close}
\end{tabular}};
\draw[->] (E) -- (F) node[midway,sloped,above]{\verb$FIN$};

\coordinate (G) at ($(A)!.4!(B)$);
\draw (G) node[left]{\verb$FIN_WAIT_2$};
\draw[->] (F) -- (G) node[midway,sloped,above]{\verb$ACK$};

\coordinate (H) at ($(C)!.5!(D)$);
\draw (H) node[right]{\verb$LAST_ACK$};

\coordinate (I) at ($(A)!.7!(B)$);
\draw (I) node[left]{\verb$TIME_WAIT_2$};
\draw[->] (H) -- (I) node[midway,sloped,above]{\verb$FIN$};

\coordinate (J) at ($(C)!.9!(D)$);
\draw (J) node[right]{\verb$CLOSED$};
\draw[->] (I) -- (J) node[midway,sloped,above]{\verb$ACK$};
\end{tikzpicture}
\end{center}
\end{document} 

diagram

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .