TCP/IPは、インターネットとほとんどのコンピュータネットワークの基盤を形成するプロトコルスタックです。信頼性の高いデータ配信を担当するTCPプロトコルと、ノード間のパケットルーティングを確保するIPを統合します。IETF RFC 1180(2024)によると、TCP/IPスタックはモバイルアプリケーションやウェブアプリケーションを含む、世界のネットワークトラフィックの80%以上を処理しています。プロトコルスタックは、データがどのようにパッケージ化、アドレス指定、ネットワーク上のデバイス間で送信されるかを定義します。
重要なポイント
TCP/IP(Transmission Control Protocol / Internet Protocol)は、1970年代にARPANET向けに開発され、グローバルインターネットのデファクトスタンダードとなったプロトコルスタックです。データがどのようにパケットに分割され、アドレス指定され、送信され、受信側で再構築されるかを定義します。
TCP/IPアーキテクチャは多層原則に基づいて構築されており、各層が特定の機能を抽象化します。アプリケーション層はアプリケーションデータを扱い、トランスポート層は信頼性を確保し、ネットワーク層はルーティングを処理し、リンク層は物理的な伝送を管理します。モジュール性により、隣接する層に影響を与えることなく、層内のプロトコルを置き換えることができます。
モバイル開発では、TCP/IPはネットワークリクエストを行うすべてのアプリケーションで使用されます。URLSession、OkHttp、AFNetworking、Alamofireなどのライブラリはこのスタック上で動作し、パケットのパッケージ化やルーティングの詳細を開発者から隠します。ただし、パフォーマンス最適化にはTCP/IPの理解が必要です。URLSessionConfigurationを介したTCPパラメータの設定により、タイムアウトの管理、HTTP永続接続の維持、エンタープライズ環境用のプロキシ設定が可能になります。
ネットワーク問題の診断にはTCP/IPの理解が不可欠です。アプリケーションがサーバーに接続できない場合、問題は物理チャネルからアプリケーションプロトコルまで、スタックのどの層にも存在する可能性があります。tcpdump、Wireshark、Charles Proxyなどのツールを使用すると、各層のトラフィックを分析し、ボトルネックを見つけることができます。モバイル開発者向けに、XcodeはNetwork Debug Dashboardを提供し、Android StudioはリアルタイムでTCP接続を分析するNetwork Inspectorを提供しています。
TCP/IPモデルには4つの層が含まれており、各層はデータ伝送中に厳密に定義された機能を実行します。この階層を理解することは、ネットワーク問題の診断とアプリケーションの最適化に必要です。
アプリケーション層では、アプリケーションが直接対話するプロトコルが動作します:HTTP、HTTPS、FTP、SMTP、DNS、WebSocket。この層はアプリケーションが理解できる形式でデータをフォーマットし、トランスポート層に渡します。モバイルアプリケーション開発者は、ネットワークライブラリを介してこの層で作業します。
トランスポート層は、異なるデバイス上のアプリケーション間のデータ伝送を保証します。主なプロトコルはTCP(確認応答付きの信頼性の高い伝送)とUDP(保証なしの高速伝送)です。TCPはデータに送信元と宛先のポートを追加し、パケット順序を管理し、ネットワーク輻輳を制御します。
ネットワーク層はIPプロトコルによって実装され、アドレッシング(IPv4、IPv6)とパケットルーティングを定義します。各パケットには送信元と宛先のIPアドレスが含まれ、経路上のルーターはルーティングテーブルに基づいて次のノードを決定します。IPv4は32ビットアドレス(約43億)を使用し、IPv6は128ビットアドレスを使用して、アドレス枯渇問題を解決します。
リンク層は物理伝送媒体(Ethernet、Wi-Fi、Bluetooth)を扱います。この層はパケットを信号に変換し、MACアドレスを介した伝送媒体へのアクセスを管理し、フレームチェックシーケンス(FCS)を使用して物理層のエラーを検出します。
リンク層では、ローカルネットワーク内のデバイスのIPアドレスをMACアドレスに変換するARP(Address Resolution Protocol)や、VPN接続やモバイルデータネットワークで使用されるPPP(Point-to-Point Protocol)などのプロトコルが動作します。
| 層 | プロトコル | 機能 |
|---|---|---|
| アプリケーション | HTTP, HTTPS, DNS, FTP, WebSocket | アプリケーションデータのフォーマット |
| トランスポート | TCP, UDP | アプリケーション間の伝送、エラー制御 |
| ネットワーク | IP, ICMP, ARP | パケットルーティングとアドレッシング |
| リンク | Ethernet, Wi-Fi, PPP | 物理媒体による伝送 |
TCP(Transmission Control Protocol)は、トランスポート層の主要なプロトコルの1つです。アプリケーション間でのバイトストリームの信頼性が高く、順序付けられ、エラーチェックされた配信を保証します。データを送信する前に、TCPはスリーウェイハンドシェイクを介して接続を確立します。
スリーウェイハンドシェイクは、クライアントがSYNパケットを送信することから始まります。サーバーはSYN-ACKパケットで応答し、受信を確認します。クライアントはACKパケットでハンドシェイクを完了し、その後データ伝送が開始されます。このプロセスにより、両者が交換の準備ができており、シーケンス番号で同期していることが保証されます。
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('example.com', 80))
sock.send(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
response = sock.recv(4096)
print(response.decode())
sock.close()
この例では、SOCK_STREAMタイプのTCPソケットが作成され、connectが呼び出されると自動的にスリーウェイハンドシェイクを実行します。sendメソッドはHTTPリクエストを送信し、recvは応答を受信します。完了後、closeはFINパケットを送信して接続を適切に閉じます。
スレッドを介して複数のクライアントを受け入れるPythonのTCPサーバーの例を見てみましょう。各接続は個別のスレッドで処理され、メインループをブロックせずに複数のクライアントを同時に処理できます。
import socket
import threading
def handle_client(conn, addr):
print(f'クライアント接続済み: {addr}')
with conn:
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data.upper())
print(f'クライアント {addr} 切断済み')
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 9090))
server.listen(5)
print('TCPサーバーがポート9090で起動しました')
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
TCPサーバーは各接続を個別のスレッドで処理し、無限ループでacceptを呼び出します。handle_client関数はデータを受信し、大文字に変換してsendallで送り返します。recvループが終了すると(クライアントが接続を閉じたとき)、スレッドは終了し、ソケットは自動的に閉じられます。モバイルアプリケーションでは、このような低レベルのソケット操作は直接使用されません。モバイルHTTPライブラリはスレッドプールを介して接続を管理し、TCP接続を自動的に再利用します。
TCPとUDPの選択は、ネットワーク通信を設計する際の重要な決定事項の1つです。TCPは、追加のレイテンシを犠牲にして、配信、順序、データ整合性を保証します。UDPは、最小限のレイテンシと低いチャネル負荷のために信頼性を犠牲にします。
| 特性 | TCP | UDP |
|---|---|---|
| 接続 | 確立する(ハンドシェイク) | 確立しない |
| 信頼性 | 配信を保証 | 保証しない |
| パケット順序 | 順序付ける | 順序付けない |
| 速度 | 低い | 高い |
| 使用例 | Web、メール、ファイル | ストリーミング、ゲーム、DNS |
モバイルアプリケーションの場合、プロトコルの選択はシナリオによって異なります。REST APIやデータ読み込みにはTCPが必要で、ビデオ通話やオンラインゲームはUDPの速度の恩恵を受けます。一部のアプリケーションは両方のプロトコルを組み合わせます。制御用にTCP、メディアストリーミング用にUDPを使用します。UDP上で動作しHTTP/3で使用される最新のQUICプロトコルは、両方のアプローチの利点を組み合わせ、iOSおよびAndroidでURLSessionを介して自動的にサポートされています。
エラー処理とタイムアウトを備えたPythonのTCPクライアントの例を見てみましょう。このアプローチは、モバイルアプリケーションでの信頼性の高いサーバー接続に使用されます。
import socket
import sys
def tcp_client(host, port):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect((host, port))
print(f'{host}:{port} に接続しました')
return sock
except socket.error as err:
print(f'接続エラー: {err}')
sys.exit(1)
sock = tcp_client('api.example.com', 443)
sock.close()
tcp_client関数はホストとポートを受け取り、10秒のタイムアウトでソケットを作成し、接続を試みます。接続エラー時(サーバーが利用できない、ファイアウォールがブロックしているなど)には、問題の説明とともに例外がスローされます。モバイルアプリケーションでは、接続タイムアウトは重要です。短すぎると低速ネットワークで誤ったエラーが発生し、長すぎるとインターフェースがフリーズします。モバイルネットワークの推奨値は、URLSession設定でtimeoutIntervalForRequestに10〜15秒、timeoutIntervalForResourceに30〜60秒です。
よくある質問
IPはルーティングを担当し、中間ノードを介して送信元から宛先にパケットを配信します。TCPは信頼性の高いデータアセンブリを保証し、順序を制御し、整合性をチェックし、失われたパケットの再送信を要求します。一緒にTCP/IPスタックを形成します。
TCP/IPは固定ポートを使用しません。ポートはアプリケーションによって割り当てられます。標準ポート:80(HTTP)、443(HTTPS)、22(SSH)、25(SMTP)。ポート443は、モバイルアプリケーションにおけるセキュアなWebトラフィックの主要ポートです。
TCP接続は、スリーウェイハンドシェイク(SYN、SYN-ACK、ACK)を介して確立される2つのアプリケーション間の論理チャネルです。接続は送信元と宛先のペア(IPアドレス、ポート)によって識別されます。ハンドシェイクにより、両者がデータ交換の準備ができていることが保証されます。
はい、TCP/IPはインターネットアクセスなしでローカルネットワーク(LAN)で動作します。デバイスはWi-Fi Direct、Bluetooth PAN、またはEthernetを介して接続し、ローカルIPアドレスを使用してデータを交換します。ローカルTCP/IPはIoTデバイスやピアツーピアアプリケーションで使用されます。
TCPは追加のメカニズムがあるため遅くなります:送信前のスリーウェイハンドシェイク、各パケットの確認応答、失われたセグメントの再送信、輻輳制御。UDPはこれらのチェックなしでデータグラムを送信し、損失の可能性と引き換えにレイテンシを低減します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。