0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ソケット通信の仕組みとTCP/UDPの違い】実装して感じた違和感と学び

Posted at

はじめに

以前、Pythonでサーバーを自作していたときに、こんな疑問が浮かびました。

「recv(1024)って指定しても、TCPだと全部届かないときあるのに、UDPは一発で届く…なんで?」

それまではなんとなく「TCPは信頼性があってUDPは速いけど雑」くらいの認識だったけど、このリアルな違和感から調べた結果、ソケットの仕組みやTCP/UDPの本質がストンと腹落ちしました。

この記事では、そのときの疑問→調査→理解をベースに、ソケット通信の本質とプロトコルの違いを整理します。

以下は、Pythonで開発した TCP/UDP ソケットを用いて独自のサーバーとプロトコルを実装したシンプルなチャットメッセンジャーアプリです。
https://github.com/ga-techcraft/Online-Chat-Messenger


そもそもソケット通信ってどこに保存されてるの?

パイプの理解をベースにすると

  • パイプはカーネルのリングバッファ(メモリ)に一時的に保存
  • アプリはファイルディスクリプタを通じてバッファに読み書き

ソケットも同じ

ソケットも、カーネルの送信バッファ・受信バッファに保存されている!

アプリ → write() → カーネルの送信バッファ → ネットワークへ
アプリ ← read()  ← カーネルの受信バッファ ← ネットワークから

TCPやUDPは、その送受信の過程でデータの整形や再構築をしている


TCPとUDPの違いって何?

特徴 TCP UDP
データ構造 バイトストリーム〜流れる水 メッセージ〜1通ずつ
分割・再構築 プロトコルが自動で分割 / 復元 1パケット = 1通
境界 なし(アプリが分ける必要あり) あり(1送信 = 1受信)
信頼性 高い〜再送、順序保証あり なし(失われることも)

recv(1024) で感じた違和感と答え

TCP の場合

conn.sendall(b"HELLO")
conn.sendall(b"WORLD")

data = conn.recv(1024)

data == b"HELLOWORLD"になることもあるし,分割されてることもある

理由:TCPは流れだから。どこまでが1通かは自分で判断する必要がある

UDP の場合

sock.sendto(b"HELLO", addr)
sock.sendto(b"WORLD", addr)

data, _ = sock.recvfrom(1024)

data == b"HELLO" (2回目のrecvfrom()b"WORLD"が来る)

理由:UDPは「メッセージ」だから。送信 = 受信が保証されている


まとめ

ポイント 理解
保存元 カーネルの送受信バッファ(RAM上)
TCP 流れのデータ。区切りなし。自分で分ける必要あり
UDP 送信 = 受信の1通単体。一発で取得。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?