A minimal Java gRPC "Hello" service to practice packet captures. This doc chronicles the exact steps we took—from building the app to decoding protobuf payloads captured on loopback.
mvn -q -DskipTests package
This compiles the proto at src/main/proto/helloworld.proto and generates the server/client classes:
click.yinsb.helloworld.GreeterServerclick.yinsb.helloworld.GreeterClient
Server (terminal 1):
mvn -q exec:java -Dexec.mainClass=click.yinsb.helloworld.GreeterServer
Client (terminal 2):
mvn -q exec:java -Dexec.mainClass=click.yinsb.helloworld.GreeterClient -Dexec.args="Alice"
You should see Reply: Hello Alice.
While the server is running, capture port 50051:
sudo tcpdump -i lo0 -s 0 -w hello.pcap tcp port 50051
s -0 ensures full packets, -w writes a PCAP file for Wireshark. Press Ctrl+C after running the client once; you’ll now have hello.pcap.
Open hello.pcap and filter:
grpc- or
tcp.stream eq <n>thenFollow → HTTP/2 Stream
You should see:
POST /helloworld.Greeter/SayHellogrpc-java-netty/1.67.xuser agent- Request headers (authority, path, TE, grpc-encoding)
- DATA frames with
gRPC Message: /helloworld.Greeter/SayHello, Request
Since the service is plaintext, Wireshark can decode HTTP/2 + gRPC without TLS keys.
In the packet details pane, select "gRPC Message ... Request" → Export Packet Bytes... → save as req.bin. Do the same for the response.
If you exported from the gRPC Message node, the file already contains the raw protobuf bytes (no 5-byte gRPC prefix). Decode them with protoc:
protoc --decode=helloworld.HelloRequest src/main/proto/helloworld.proto < req.bin
protoc --decode=helloworld.HelloReply src/main/proto/helloworld.proto < resp.bin
You’ll get:
name: "Alice"
message: "Hello Alice"
If you export the entire DATA frame instead, strip the 5-byte prefix (dd if=req.bin of=req.pb bs=1 skip=5). The prefix structure is:
- byte 0: compressed flag (0 = no compression)
- bytes 1–4: message length (big endian)
- Temporal dev server uses plaintext gRPC on
127.0.0.1:7233, same decoding approach works there. - Loopback traffic never appears on
en0; capture onlo0. - Wireshark can decode protobuf fields only if it knows the
.proto. When you supply the schema (or inspect withprotoc), you’ll see the fields (e.g.,name: "Alice"). Follow HTTP/2 Streamis the fastest way to correlate request/response pairs for gRPC.
Now you have a reference walkthrough tying together tcpdump, Wireshark, and protoc for gRPC payload inspection.