😺

gRPC Bidirectional streaming 通信の内容を Wireshark で確認する

2022/08/06に公開

gRPC Bidirectional streaming 通信のパケットを解析してみます。

Wireshark の設定方法などは過去の記事に簡単に書いているので参考にしてください。

解析対象のサーバ・クライアントプログラムも前回のものを使います。

パケット解析

Bidirectional streaming RPC

処理の流れ

  1. クライアントが BidirectTransform に Transform を複数件投げる
  2. サーバが Transform を複数件返す

  • No.73 - 75 c <=> s
    • TCP 3 way handshake
  • No.76 - 77 c => s
    • HTTP2 Magic
  • No.78 - 83 c <=> s
    • HTTP2 Settings
  • No.84 - 85 c => s
    • HTTP2 Settings
    • HTTP2 Header POST /grpc.GameService/BidirectTransform
  • No.86 - 87 c => s
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
    • HTTP2 DATA End Stream
  • No.88 - 89 s => c
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.90 - 91 c => s
    • HTTP2 PING Pong
  • No.92 - 93 s => c
    • HTTP2 Headers 200 OK
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
  • No.94,95 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 9件続く)
  • No.96 - 97 s => c
    • HTTP2 DATA grpc.Transform
  • No.98 - 99 c => s
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.100 - 101 s => c
    • HTTP2 PING Pong
  • No.102 - 103 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
  • No.104 - 105 c => s
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.106 - 107 s => c
    • HTTP2 PING Pong
  • No.108 - 109 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
  • No.110 - 111 c => s
    • HTTP2 WINDOW_UPDATE
  • No.112 - 113 c => s
    • HTTP2 PING Ping
  • No.114 - 115 s => c
    • HTTP2 PING Pong
  • No.116 - 117 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
  • No.118 - 119 c => s
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.120 - 121 s => c
    • HTTP2 PING Pong
  • No.122 - 123 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
  • No.124 - 125 c => s
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.126 - 127 s => c
    • HTTP2 PING Pong
  • No.128 - 129 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
  • No.130 - 131 c => s
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.132 - 133 s => c
    • HTTP2 PING Pong
  • No.134 - 135 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 7件続く)
  • No.136,139 c => s
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.137,138 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 3件続く)
  • No.139 - 141 s => c
    • HTTP2 PING Pong
  • No.142 - 143 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
  • No.144 - 145 c => s
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.146 - 147 s => c
    • HTTP2 PING Pong
  • No.148 - 149 s => c
    • HTTP2 DATA grpc.Transform
    • (snip 10件続く)
  • No.150,152 c => s
    • HTTP2 WINDOW_UPDATE
    • HTTP2 PING Ping
  • No.151 - 152 s => c
    • HTTP2 Headers End Stream
  • No.154 - 155 s => c
    • HTTP2 PING Pong
  • No.156
    • TCP rst

TCP 3 way handshake, HTTP2 Magic, HTTP2 Settings までは Unary RPC, Server streaming RPC と変わらず。

No.84 - 87 がクライアントがリクエストしているところ。

  1. No.84 - 85 でクライアントからヘッダを送信
  2. No.86 - 87 でクライアントから Transform データ(553 Bytes)を 10 件送信

No.94 からサーバからクライアントへデータを送信開始

  1. サーバから HTTP2 DATA grpc.Transform
  2. クライアントから HTTP2 WINDOW_UPDATE
  3. クライアントから HTTP2 PING Ping
  4. サーバから HTTP2 PING Pong

を繰り返しています。

Transform は 1 件あたり 48 Bytes でデータ構造は前回と変わらず。

サーバからクライアントへのデータ送信を見る限り、for で 10 回 stream.Send するコードを書いたからといって、10 件ずつ 1 TCP セグメントで出力されるわけではなく、9 件だったり、7 件だったり、状況によっては別 TCP セグメントになっていることがわかります。

Summary

解析は以上です。

双方向になっただけで Server streaming, Client streaming と基本的な構造は同じように思いました。

Discussion