TCPのチェックサムとは?エラー検出の仕組みも!(誤り検出:ヘッダ:計算方法:オフロード:整合性確認など)
ネットワーク通信において、データが正しく届いているかどうかを確かめる仕組みは非常に重要です。インターネットを通じてやりとりされるデータは、途中でビットが化けたり、パケットが壊れたりする可能性があります。そのようなデータの誤りを検出するための仕組みとして、TCPには「チェックサム」と呼ばれる機能が備わっています。
本記事では、TCPチェックサムの概要からヘッダ構造、計算方法、オフロード機能、そして整合性確認の手順まで、幅広く解説していきます。ネットワークの信頼性を支えるこの仕組みを、ぜひしっかり押さえておきましょう。
TCPチェックサムとは何か?誤り検出の中核を担う機能
それではまず、TCPチェックサムの基本的な概念と、ネットワーク通信における役割について解説していきます。
チェックサムの役割と誤り検出の基本
TCPチェックサムとは、送受信されるデータに誤りが生じていないかを検出するための数値です。送信側がデータをもとに計算した値をパケットに付加し、受信側が同じ計算を行って値を照合します。値が一致しない場合は、データに何らかの異常が生じたと判断されます。
このチェックサムによる誤り検出は、TCPが「信頼性のある通信」を実現するための根幹のひとつです。TCPはUDPとは異なり、データの到達保証や順序制御といった機能を持っており、チェックサムはその信頼性を支える重要な要素でしょう。

TCP/IPプロトコルスタックにおける位置づけ
TCPはOSI参照モデルにおけるトランスポート層に位置します。IPがネットワーク層で動作するのに対し、TCPはその上位で機能し、エンドツーエンドの通信品質を管理します。
チェックサムはTCPヘッダに格納されており、TCPセグメント全体(ヘッダとデータ部分)を対象として計算が行われます。ただし、計算には後述する「擬似ヘッダ」も含まれるため、IPアドレス情報も間接的に関与している点が特徴的です。
UDPとの比較で見るチェックサムの重要性
UDPにもチェックサムフィールドは存在しますが、UDPではチェックサムの使用が任意(オプション)とされている場合があります。一方、TCPではチェックサムの使用が必須であり、省略することはできません。
これはTCPが「確実に正しいデータを届ける」という設計思想のもとに作られているためです。リアルタイム性を重視するUDPとは対照的に、TCPは信頼性を最優先に設計されているといえるでしょう。
| 項目 | TCP | UDP |
|---|---|---|
| チェックサムの使用 | 必須 | 任意(IPv4)/必須(IPv6) |
| 誤り検出時の動作 | パケット破棄+再送要求 | パケット破棄のみ |
| 通信の信頼性 | 高い | 低い(速度重視) |
| 主な用途 | Web、メール、ファイル転送 | 動画配信、DNS、VoIP |
TCPヘッダの構造とチェックサムフィールドの場所
続いては、TCPヘッダの構造とチェックサムフィールドの詳細を確認していきます。
TCPヘッダのフィールド一覧
TCPヘッダには複数のフィールドが定義されており、通信の制御に必要な情報が格納されています。標準的なTCPヘッダのサイズは20バイト(オプションなし)です。
| フィールド名 | サイズ | 説明 |
|---|---|---|
| 送信元ポート番号 | 16ビット | 送信元のポート番号 |
| 宛先ポート番号 | 16ビット | 宛先のポート番号 |
| シーケンス番号 | 32ビット | データの順序を管理 |
| 確認応答番号 | 32ビット | 受信確認に使用 |
| データオフセット | 4ビット | ヘッダ長を示す |
| 制御フラグ | 6ビット | SYN、ACK、FINなど |
| ウィンドウサイズ | 16ビット | フロー制御に使用 |
| チェックサム | 16ビット | 誤り検出用の値 |
| 緊急ポインタ | 16ビット | 緊急データの位置を示す |
チェックサムフィールドの詳細
チェックサムフィールドは16ビット(2バイト)のサイズを持ち、TCPヘッダの中でウィンドウサイズの直後に配置されています。このフィールドには、後述する計算方法によって算出された値が格納されます。
送信時にはチェックサムフィールドをいったん0に設定した状態で計算を行い、算出された値をそのフィールドに書き込みます。受信側では同じ手順で計算を行い、すべてのビットが1になる(16進数でFFFF)ことを確認します。一致しない場合、データに誤りがあると判断されるわけです。
擬似ヘッダ(Pseudo Header)の概念
TCPチェックサムの計算には、TCPヘッダとデータに加えて「擬似ヘッダ(Pseudo Header)」と呼ばれる仮想的な構造体が用いられます。擬似ヘッダは実際にはネットワーク上を流れませんが、計算の精度を高めるために内部的に使用されます。
擬似ヘッダには以下の情報が含まれます。
| フィールド | サイズ | 内容 |
|---|---|---|
| 送信元IPアドレス | 32ビット | 送信元のIPv4アドレス |
| 宛先IPアドレス | 32ビット | 宛先のIPv4アドレス |
| 予約フィールド | 8ビット | 常に0 |
| プロトコル番号 | 8ビット | TCP=6 |
| TCPセグメント長 | 16ビット | ヘッダ+データの合計バイト数 |
擬似ヘッダをチェックサム計算に含めることで、IPアドレスが途中で改ざんされた場合にも誤りを検出できる可能性が高まります。これはセキュリティ上の観点からも重要な仕組みでしょう。
TCPチェックサムの計算方法を詳しく解説
続いては、TCPチェックサムの具体的な計算手順を確認していきます。
1の補数和による計算の仕組み
TCPチェックサムは「1の補数和(One’s Complement Sum)」という方法で計算されます。この手順は以下のとおりです。
まず、擬似ヘッダ、TCPヘッダ(チェックサムフィールドは0として)、データ部分をすべて16ビット単位に分割します。次に、すべての16ビット値を加算し、桁上がりが発生した場合はその桁上がりを下位ビットに加算します(エンドアラウンドキャリー)。最後に、合計値のビットをすべて反転(ビット反転=1の補数)した値がチェックサムになります。
Pythonによるチェックサム計算のサンプルコード
実際にPythonでTCPチェックサムを計算するサンプルを見てみましょう。擬似ヘッダとTCPセグメントを組み合わせて計算する例です。
import struct
import socketdef calculate_checksum(data):
# 16ビット単位で加算する
s = 0
for i in range(0, len(data) - 1, 2):
w = (data[i] << 8) + data[i + 1]
s += w
# データ長が奇数の場合は最後の1バイトを処理する
if len(data) % 2 != 0:
s += data[-1] << 8 # エンドアラウンドキャリーの処理 while s >> 16:
s = (s Sonnet 4.6