tcp

TCP three-way handshake

What to watch

SYN, SYN-ACK, ACK and the state changes on both ends

Seed: 1 (default). The program asks a question at the interesting moment; with Predict on, the run stops there so you can answer before you see what happens.

Run it

Edit any file and press Run. The tabs hold the program and the packages it uses.

# package main
use github.com/synodlang/examples/tcp
use std/lesson
use std/sim

define main
  set client to (sim.Spawn tcp)
  set server to (sim.Spawn tcp)
  set server.tcp.State to "LISTEN"
  lesson.Note "A connection needs three messages before data can flow."
  deliver (message tcp.Open with Server server) to client
  after 5ms
    lesson.Ask "What does the server send back after a SYN?" choosing {"An ACK, and the connection is open", "A SYN-ACK: its own sequence number and an acknowledgment of the client's", "A FIN, closing the connection", "Nothing until the client sends data"}
  after 100ms
    lesson.Note "Both ends are ESTABLISHED: data can now flow either way."
  sim.StopAt 200ms
# package tcp
use std/net
use std/sim

Open has
  set Server to sim.Nobody

Syn has
  set Seq to 0

SynAck has
  set Seq to 0
  set AckNo to 0

Ack has
  set AckNo to 0

Node has
  set State to "CLOSED"
  set seq to 0
  set peerSeq to 0

# Client: the application asks to open a connection
when [n: Node] (sim.Delivered Open)
  set n.seq to 100
  set n.State to "SYN-SENT"
  net.Send (message Syn with Seq n.seq) from n to Open.Server

# Server: answer a SYN with SYN-ACK
when [n: Node] (net.Received Syn from client)
  set n.peerSeq to Syn.Seq
  set n.seq to 300
  set n.State to "SYN-RECEIVED"
  net.Send (message SynAck with Seq n.seq, AckNo (n.peerSeq plus 1)) from n to client

# Client: a SYN-ACK that acknowledges our SYN completes our side
when [n: Node] (net.Received SynAck from server)
  if (SynAck.AckNo is (n.seq plus 1))
    set n.peerSeq to SynAck.Seq
    set n.State to "ESTABLISHED"
    net.Send (message Ack with AckNo (n.peerSeq plus 1)) from n to server

# Server: the final ACK completes the handshake
when [n: Node] (net.Received Ack from client)
  if (Ack.AckNo is (n.seq plus 1))
    set n.State to "ESTABLISHED"

On your own machine: synod run ./tcp. Source on GitHub · all examples