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