When you type a URL into your browser, it feels almost instantaneous.
You enter:
http://example.com
and a webpage appears.
But underneath that simple action, your computer performs several separate networking operations. It may need to discover the server's IP address, establish a connection, send an HTTP request, receive a response, and eventually close or reuse the connection.
Wireshark lets us watch these operations happen packet by packet.
In this tutorial, we're going to generate a simple HTTP request and trace its journey through:
DNS → TCP → HTTP → TCP termination
We'll also use Wireshark's Flow Graph to turn the packets into a visual conversation between our computer and the servers involved.
What Is Wireshark?
Wireshark is a network protocol analyzer.
It captures network traffic passing through a network interface and allows us to inspect the individual packets.
Instead of seeing:
Browser → Website
Wireshark lets us see what is actually happening:
Application
↓
HTTP
↓
TCP
↓
IP
↓
Ethernet / Wi-Fi
↓
Network
This makes Wireshark particularly useful for learning networking because concepts such as TCP handshakes, ports, DNS queries, HTTP headers, and IP addresses stop being purely theoretical.
We can actually see them.
What Happens When We Make an HTTP Request?
Before opening Wireshark, let's understand what we're looking for.
Suppose we request:
curl http://example.com
At a simplified level, the process looks like this:
Computer
│
│ "What is the IP address of example.com?"
▼
DNS Resolver
│
│ "example.com is x.x.x.x"
▼
Computer
│
│ Establish TCP connection
▼
Web Server
│
│ Send HTTP GET request
▼
Web Server
│
│ Return HTTP response
▼
Computer
There are therefore several different protocols involved in what appears to us as one operation.
We'll trace them individually.
Step 1: Start Wireshark
Open Wireshark.
You'll see a list of network interfaces available on your computer.
Examples might include:
eth0
eno1
wlan0
wlo1
lo
On my Fedora machine, the Wi-Fi interface is wlo1.
If you're unsure which interface you're using, Linux users can run:
ip addr
or:
ip link
Look for the interface that is currently active.
Select that interface in Wireshark and start capturing.
You'll immediately see packets appearing.
Don't worry if there are hundreds of them.
Your computer is constantly communicating over the network even when you aren't actively doing anything.
Step 2: Generate an HTTP Request
We're deliberately going to use HTTP instead of HTTPS.
Why?
HTTPS encrypts HTTP traffic using TLS. Wireshark would still be able to observe the connection, but we wouldn't normally be able to simply read the HTTP request and response.
Plain HTTP makes the experiment much easier to understand.
Open another terminal and run:
curl -v http://example.com
Another useful test site is:
curl -v http://httpforever.com/
The -v option tells curl to display additional information about the request.
Once the request finishes, stop the Wireshark capture.
Now we can begin investigating.
Step 3: Find the HTTP Request
Wireshark probably captured a lot more than our curl command.
Let's filter the traffic.
Enter this into the display filter:
http
You should see packets containing something similar to:
GET / HTTP/1.1
and a response such as:
HTTP/1.1 200 OK
Click the GET packet.
In the packet details panel, expand:
Hypertext Transfer Protocol
You should see information similar to:
GET / HTTP/1.1
Host: example.com
User-Agent: curl/...
Accept: */*
This is the actual HTTP request sent by our computer.
It's no longer an abstract example from a networking textbook.
That's the request that just left our machine.
Step 4: Find the TCP Connection
HTTP doesn't independently deliver the request across the Internet.
With HTTP/1.1 in this example, the HTTP messages are transported using TCP.
Right-click the HTTP GET packet and select:
Follow → TCP Stream
Wireshark will reconstruct the conversation belonging to that TCP connection.
This is also extremely useful when investigating larger packet captures because Wireshark identifies the TCP stream for us.
After identifying the stream number, close the TCP Stream window.
Suppose Wireshark identifies it as stream 4.
We can filter for the entire connection using:
tcp.stream == 4
Now instead of seeing every TCP packet captured by our computer, we see only the TCP conversation containing our HTTP request.
Step 5: Find the TCP Three-Way Handshake
Before our computer could send the HTTP request, it first needed to establish a TCP connection with the web server.
TCP does this using the famous three-way handshake:
Client Server
│ │
│──────── SYN ────────────────>│
│ │
│<────── SYN + ACK ────────────│
│ │
│──────── ACK ────────────────>│
│ │
The first packet is the client saying:
I want to establish a TCP connection.
The server responds:
I received your request, and I'm ready.
The client then acknowledges the server's response.
The connection is established.
In Wireshark, click the first TCP packet and expand:
Transmission Control Protocol
Then inspect:
Flags
The first packet should have the SYN flag set.
The response should have both SYN and ACK set.
The third packet should have ACK set.
We have now observed the TCP three-way handshake directly.
Step 6: Look at the Ports
While inspecting the TCP information, look at the source and destination ports.
You might see something resembling:
Source Port: 48732
Destination Port: 80
Port 80 is the conventional port for HTTP.
But why is our source port something random like 48732?
Our operating system chooses a temporary ephemeral port for the client side of the connection.
So our connection might effectively look like:
192.168.1.20:48732 → 93.x.x.x:80
The combination of IP addresses and ports allows the operating systems to identify the connection.
This becomes especially important because your computer may have many TCP connections open simultaneously.
Step 7: Inspect the HTTP GET Request
After the TCP connection has been established, we should eventually see:
GET / HTTP/1.1
Select that packet.
Wireshark will show several layers.
Something similar to:
Frame
└── Ethernet II
└── Internet Protocol Version 4
└── Transmission Control Protocol
└── Hypertext Transfer Protocol
This is one of my favorite parts of the experiment because it demonstrates encapsulation.
The HTTP message isn't simply thrown onto the network.
Conceptually, we have:
HTTP Request
↓
TCP Segment
↓
IP Packet
↓
Ethernet/Wi-Fi Frame
Each layer adds information required for its particular job.
HTTP understands things such as:
GET
Host
User-Agent
TCP understands things such as:
Ports
Sequence numbers
Acknowledgements
Flags
IP understands things such as:
Source IP
Destination IP
The lower network layer handles delivery over the local network.
Wireshark lets us expand these layers individually.
Step 8: Inspect the HTTP Response
The server now needs to answer our request.
Look for something similar to:
HTTP/1.1 200 OK
Depending on the website, the exact status code may be different.
Expand the HTTP section.
You might see headers such as:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: ...
The server may then send the HTML document requested by the client.
If the response is sufficiently large, it won't necessarily fit inside a single TCP segment.
You may therefore see multiple packets transporting parts of the response.
TCP is responsible for making sure that this data can be correctly reconstructed by the receiving application.
Step 9: What Happened Before TCP? DNS
There's still something missing.
How did our computer know the server's IP address?
We gave curl a domain name:
example.com
TCP ultimately needs to connect to an IP address.
This is where DNS comes in.
Remove the TCP stream filter and enter:
dns
Look for a DNS query involving the domain you requested.
You may see something resembling:
Standard query
A example.com
The A query asks for an IPv4 address.
The DNS resolver may then return something resembling:
Standard query response
A example.com
A x.x.x.x
Our computer can now use that IP address to establish the TCP connection.
One important caveat is caching.
If your operating system or local DNS resolver already knows the address, you might not see the DNS request you expect on your network interface.
Using a domain that hasn't recently been requested can make the experiment easier.
Step 10: Visualize Everything with Wireshark's Flow Graph
Reading individual packets is useful, but Wireshark has another feature that makes this experiment much easier to understand.
Go to:
Statistics → Flow Graph
Wireshark can represent network communication using arrows between endpoints.
Instead of interpreting dozens of rows, we can get something conceptually similar to:
Client Server
│ │
│──────── SYN ────────────────>│
│ │
│<────── SYN, ACK ─────────────│
│ │
│──────── ACK ────────────────>│
│ │
│────── GET / HTTP/1.1 ───────>│
│ │
│<──── HTTP/1.1 200 OK ────────│
│ │
│<──── Response Data ──────────│
│ │
This is especially useful when learning TCP because the request becomes a conversation instead of a table of packets.
The Flow Graph can also be useful as a screenshot when documenting the experiment.
Building a Clean Flow Graph
There's one trap here.
If we filter Wireshark using only:
http
and then create our graph from only displayed packets, we may hide the TCP packets.
Our graph would show the HTTP request and response but not the TCP handshake that made them possible.
Instead, identify the TCP stream associated with the HTTP request and use something like:
tcp.stream == 4
Replace 4 with your actual stream number.
Now the Flow Graph can show the entire TCP conversation rather than just HTTP packets.
For a more complete investigation, DNS can be examined separately because DNS resolution is a separate conversation from the TCP connection.
The Complete Journey
After examining the capture, we can finally reconstruct what happened when we executed one simple command:
curl http://example.com
The high-level process was:
1. Application requests example.com
↓
2. DNS resolves the domain
↓
3. Client obtains server IP
↓
4. TCP SYN
↓
5. TCP SYN-ACK
↓
6. TCP ACK
↓
7. TCP connection established
↓
8. HTTP GET request
↓
9. Server processes request
↓
10. HTTP response
↓
11. Response data transferred
↓
12. TCP connection eventually closed or reused
What appeared to be one operation was actually cooperation between several protocols.
What I Learned
Before doing this experiment, it's easy to think about HTTP as:
Computer → Website → Response
Wireshark exposes how much is hidden behind that abstraction.
DNS answers:
Where is the server?
IP answers:
Where should this packet go?
TCP handles:
How do we reliably exchange this stream of data?
HTTP handles:
What resource does the client want, and what should the server return?
Each protocol solves a different problem.
And together they make something as simple as:
curl http://example.com
possible.
That's what makes Wireshark such a useful tool for learning networking.
Instead of just reading about SYN packets, ACKs, ports, DNS queries, HTTP headers, and encapsulation, you can generate a request yourself and watch every layer do its job.
Top comments (0)