本記事(記事カラム)には広告が含まれています。

TCPでデータを送信(固定長バイト)|Python 練習 13

人気ブログランキングテキスト
記事内に広告が含まれています。
人気ブログランキングテキスト

TCP を使ってデータを送信します。 自宅無線LANのローカルで通信します。

PC からスマホに文字データ「abcdefg」を送信します。

PCをクライアント、スマホをサーバーとします。データの終了の見極めは、バイト長とします。

DMM FX広告(差し込みタイプ)
広告(PR)|自分の投資スタイルを見つける。※タップで開閉
広告(PR)

DMM FXは、「最初の一歩を踏み出す場」として選ばれることがある

口座を開いてみた。取引してみた。思ったよりも難しかった。──そんな経験が、投資との距離感を知るきっかけになることもあります。


サービスを通じて、自分の投資スタイルを見つける。それは、確信ではなくても構いません。「試してみた」という実感が、次の選択の材料になることもあるからです。


DMM FXに関する詳細は、以下の広告(PR)リンクをご覧いただけます。


👇こちらは広告(PR)リンクバナーです

DMMFX

人気ブログランキングテキスト

PC側コード(送信側 / クライアント)

# 送信側(TCP クライアント)
import socket

TARGET_IP = "192.168.0.235"  # ←受信側のIP
TARGET_PORT = 5000

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((TARGET_IP, TARGET_PORT))

message = b"abcdefg"
sock.sendall(message)

print("送信:", message, "→", TARGET_IP, TARGET_PORT)

sock.close()

PC側 コードの解説

全体の流れ

この送信プログラムは、

TCP ソケットを作る → 接続する → メッセージを送る → 終わり

という構成です。 UDP と違い、TCP は「接続してから送る」必要があります。

コードの分解と解説

1. import socket

Python の標準ライブラリ。 ネットワーク通信の基本機能が入っています。

2. 送信先の設定

TARGET_IP = "192.168.0.235"
TARGET_PORT = 5000
  • TARGET_IP:受信側(サーバ)の IP
  • TARGET_PORT:受信側が bind() して待っているポート番号

TCP も UDP と同じく、相手の IP とポート番号が必要です。

3. TCP ソケットを作る

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  • AF_INET → IPv4
  • SOCK_STREAM → TCP を使う

UDP の SOCK_DGRAM と違い、TCP はストリーム通信です。

4. サーバに接続する

sock.connect((TARGET_IP, TARGET_PORT))

TCP は「接続してから送る」方式なので、 まずサーバに接続します。

5. 送るデータを作る

message = b"abcdefg"

TCP も UDP と同じく バイト列を送ります。

6. データを送信

sock.sendall(message)
  • sendall() はデータをすべて送るまでブロックする
  • TCP はパケット分割を OS が自動で行うため、sendall() が安全

7. 送信ログ

print("送信:", message, "→", TARGET_IP, TARGET_PORT)

8. ソケットを閉じる

sock.close()

TCP は接続型なので、最後に必ず閉じます。

スマホ側コード(受信側 / サーバ)

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("0.0.0.0", 5000))
sock.listen(1)

print("waiting...")

conn, addr = sock.accept()
print("connect:", addr)

# Receive a fixed-length message of 7 bytes
expected = 7
received = b""

while len(received) < expected:
    chunk = conn.recv(expected - len(received))
    if not chunk:
        break
    received += chunk

print("received:", received.decode(), "from", addr)

conn.close()
sock.close()

スマホ側 コードの解説

全体の流れ

  • TCP ソケットを作る
  • ポート 5000 を開けて待ち受ける
  • クライアント(PC)が接続してくる
  • データを受信する
  • 表示する

UDP と違い、TCP は 接続(accept) が必要です。

コードの分解と解説

1. ソケットライブラリを読み込む

import socket

2. TCP ソケットを作る

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  • SOCK_STREAM → TCP
  • 「TCP 用の受信箱」を作るイメージ

3. ポート 5000 を開けて待ち受ける

sock.bind(("0.0.0.0", 5000))
  • "0.0.0.0" → すべてのネットワークインターフェースで受信
  • 5000 → このスマホ(または PC)の受信ポート番号

4. 接続待ち行列を作る

sock.listen(1)
print("waiting...")

sock.listen(1) の「1」は、接続待ち行列の長さ。

5. クライアントからの接続を受け付ける

conn, addr = sock.accept()
print("connect:", addr)

accept() は クライアントからの接続要求が来るまで待つ(ブロックする) 関数です。 クライアントが connect() を呼ぶと接続が成立し、accept() が解除されて次の行へ進みます。

addr には (クライアントIPアドレス, クライアント側ポート番号) のタプルが入ります。

(補足)クライアント側のポート番号は OS が毎回自動的に割り当てるため、接続のたびに異なるポート番号になるのが普通です(固定ではありません)。

6. データを受信(固定長バイト)

# Receive a fixed-length message of 7 bytes
expected = 7
received = b""

while len(received) < expected:
    chunk = conn.recv(expected - len(received))
    if not chunk:
        break
    received += chunk
固定長受信が必要になる背景

TCP は ストリーム(バイトの流れ) であり、次の性質があります。

  • 送信したデータは 分割されることがある
  • 複数の send が まとめられることがある
  • recv() は「届いた分だけ返す」
  • メッセージの終わりは TCP が教えてくれない
  • しかし 順番は必ず保証される

そのため、アプリ側で「どこまでが1メッセージか」を決める必要があります。 固定長方式はその最もシンプルで堅牢な方法です。

コードの各行が果たす役割
1. 必要なバイト数を決める
expected = 7
received = b""
  • 今回は 7 バイトが 1 メッセージ と決めている
  • received は受信した断片(chunk)をつなげていくバッファ
2. 必要なバイト数が揃うまでループする
while len(received) < expected:
  • TCP は分割されるため、1 回の recv で 7 バイト揃うとは限らない
  • だから 必要な長さに達するまで繰り返す
3. 足りない分だけ recv する
chunk = conn.recv(expected - len(received))
  • すでに受け取った分を除いた「残りの必要バイト数」だけ要求する
  • ただし実際に届く量は OS が決めるので、もっと少ないこともある
  • これが chunk(断片)
4. if not chunk: の意味
if not chunk:
    break

ここが最も誤解されやすい部分ですが、意味はこうです。

recv() が空の b”” を返すのは「相手が切断した」時

Python では次の値は「偽(False)」とみなされます。

  • 0
  • ""
  • b"" ← 今回これ
  • []
  • None

つまり if not chunk:

chunk が空(b””)なら True → 相手が切断したのでループを終了する

という意味です。

これがないと無限ループになる

相手が 7 バイト送る前に切断した場合:

  • recv → b”ABC”
  • recv → b””(切断)

if not chunk: がないと、 len(received) < expected が永遠に True のままになり、無限ループします。

5. 断片をつなげていく
received += chunk
  • TCP は分割されるので、断片をつなげて 7 バイトにする
  • 順番は TCP が保証してくれるので安心して連結できる

7. 受信内容を表示

print("received:", received.decode(), "from", addr)

8. 接続を閉じる

conn.close()
sock.close()

TCP は接続型なので、最後に必ず閉じます。

結果

最初にスマホ側(サーバ)を起動。 次に PC 側(クライアント)を起動します。

PC から送信した「abcdefg」が表示されます。

スマホ側(受信)画面

人気ブログランキング ブログパーツ

もしも


人気ブログランキングバナー

人気ブログランキング

人気ブログランキングテキスト