[Python]在同一台電腦上,使用 TCP/IP 讓兩個程式互相通訊

更新 發佈閱讀 9 分鐘

💻 在同一台電腦上讓程式互通:TCP/IP Socket 原理與實作

🧠 一、為什麼同一台電腦也能用 TCP/IP 通訊?

很多人以為 TCP/IP 只用在「跨網路」的通訊,其實不然。

TCP/IP 是一種協定(Protocol),而非實體連線。

Windows、macOS、Linux 都有「網路堆疊(Network Stack)」模組,

當兩個程式使用 TCP/IP 時,它們其實透過作業系統內部的「回送介面(Loopback Interface)」來交換資料。

成果畫面

raw-image



這個介面對應的 IP 是:

127.0.0.1 或 localhost

代表「我自己這台電腦」。


🔌 二、運作原理簡介

TCP(Transmission Control Protocol)是「可靠、連線導向」的協定。

它的通訊模型如下:

客戶端(Client) → 伺服器(Server)

1️⃣ 伺服器端

  • 綁定(bind)在一個特定的 IP + Port
  • 監聽(listen)連線
  • 接收到請求後進入通訊(accept → recv → send)

2️⃣ 客戶端

  • 建立 socket
  • 嘗試連線到伺服器 IP + Port
  • 傳送資料(send)
  • 等待伺服器回應(recv)

3️⃣ 作業系統負責封包交換與資料緩衝


即使雙方都在同一台電腦上,也會經過 TCP 的流程,只是不會經過實體網卡。



🧩 三、實際範例 — 讓 PyQt5 GUI 與 TCP Server 通訊

這裡我們做一個非常直覺的示範:

  • server.py:簡單的 TCP 伺服器,接收訊息並回覆。
  • client_ui.py:PyQt5 介面,讓使用者輸入訊息並發送。

結構如下:

tcp_demo/
├── server.py
└── client_ui.py

🖥️ server.py — TCP 伺服器

import socket

def run_server(host='127.0.0.1', port=5000):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
print(f"✅ 伺服器啟動於 {host}:{port},等待連線中...")

while True:
conn, addr = s.accept()
print(f"🔗 來自 {addr} 的連線")
data = conn.recv(1024)
if not data:
break
print("📨 收到訊息:", data.decode())
conn.sendall("伺服器已收到!".encode("utf-8"))
conn.close()

if __name__ == "__main__":
run_server()

📘 說明:

  • socket.AF_INET → 使用 IPv4
  • socket.SOCK_STREAM → 使用 TCP
  • bind() 綁定 IP 與 Port
  • listen() 等待連線
  • accept() 等待客戶端進入
  • recv() 接收資料
  • sendall() 回傳資料

🧰 client_ui.py — PyQt5 客戶端

import sys
import socket
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLabel, QLineEdit

class TCPClientUI(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("PyQt5 TCP 客戶端")
self.resize(300, 200)

self.layout = QVBoxLayout()
self.label = QLabel("輸入要傳送的訊息:")
self.textbox = QLineEdit()
self.btn_send = QPushButton("送出")
self.status = QLabel("狀態:未連線")

self.layout.addWidget(self.label)
self.layout.addWidget(self.textbox)
self.layout.addWidget(self.btn_send)
self.layout.addWidget(self.status)
self.setLayout(self.layout)

self.btn_send.clicked.connect(self.send_message)

def send_message(self):
msg = self.textbox.text()
if not msg:
self.status.setText("⚠️ 請輸入訊息")
return

try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 5000))
            s.sendall(msg.encode("utf-8"))
            data = s.recv(1024).decode("utf-8")
s.close()
self.status.setText(f"✅ 已送出,伺服器回覆:{data}")
except Exception as e:
self.status.setText(f"❌ 錯誤:{e}")

if __name__ == "__main__":
app = QApplication(sys.argv)
win = TCPClientUI()
win.show()
sys.exit(app.exec_())

📘 說明:

  • 使用 PyQt5 製作 GUI。
  • 使用 socket.connect() 連上本機伺服器。
  • sendall() 傳送輸入的文字。
  • recv() 等待伺服器回覆。
  • 結果顯示在介面上。

🚀 四、執行步驟

1️⃣ 啟動伺服器

python server.py

會看到:

✅ 伺服器啟動於 127.0.0.1:5000,等待連線中...

2️⃣ 開啟客戶端

python client_ui.py

輸入「Hello」按下送出。

結果:

  • PyQt5 視窗顯示:「伺服器已收到!」
  • 伺服器端顯示:
    🔗 來自 ('127.0.0.1', 60324) 的連線
    📨 收到訊息: Hello
留言
avatar-img
留言分享你的想法!
avatar-img
螃蟹_crab的沙龍
155會員
302內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。 興趣是攝影,踏青,探索未知領域。 人生就是不斷的挑戰及自我認清,希望老了躺在床上不會後悔自己什麼都沒做。
螃蟹_crab的沙龍的其他內容
2025/09/26
測試Python 3.12.10版本與目前使用的3.87版本 差異 參考以下文章 在 Python 3.8.6 vs 3.12.10 上跑同一組程式,比較不同類型任務的效能差異。 成果彙整 程式碼參考如下 🧮 數值運算密集 (CPU bound) import time def
Thumbnail
2025/09/26
測試Python 3.12.10版本與目前使用的3.87版本 差異 參考以下文章 在 Python 3.8.6 vs 3.12.10 上跑同一組程式,比較不同類型任務的效能差異。 成果彙整 程式碼參考如下 🧮 數值運算密集 (CPU bound) import time def
Thumbnail
2025/09/04
1. 什麼是物件的記憶體位置? 在 Python 中,每個物件在記憶體中都有一個唯一的位置,這個位置可以用 id() 函式查詢。 這個 id 在 CPython(最常見的 Python 實作)中,實際上就是物件的記憶體地址。 a = [1, 2, 3] print(id(a))
2025/09/04
1. 什麼是物件的記憶體位置? 在 Python 中,每個物件在記憶體中都有一個唯一的位置,這個位置可以用 id() 函式查詢。 這個 id 在 CPython(最常見的 Python 實作)中,實際上就是物件的記憶體地址。 a = [1, 2, 3] print(id(a))
2025/04/25
在 Python 中,字典(dict)是非常常用的資料結構,用來儲存 key-value 配對。而在操作字典時,.setdefault() 是一個常被忽略但非常實用的方法。 這篇文章會完整介紹 .setdefault() 的語法、用途、與實務範例,幫助你更有效率地處理字典資料。 什麼是 .se
Thumbnail
2025/04/25
在 Python 中,字典(dict)是非常常用的資料結構,用來儲存 key-value 配對。而在操作字典時,.setdefault() 是一個常被忽略但非常實用的方法。 這篇文章會完整介紹 .setdefault() 的語法、用途、與實務範例,幫助你更有效率地處理字典資料。 什麼是 .se
Thumbnail
看更多
你可能也想看
Thumbnail
最近開始轉涼了,各位鳥奴們是否會開始擔心小鳥會著涼呢?不用擔心,今天這篇直接帶你看需要的商品,而且今天除了照片之外,我們也直接帶連結✨讓你的雙11購物不盲目,讓你想買直接加入購物車,除了長知識也可以直接下單避寒神器🫱🏼文章結尾也會告訴大家在花錢的同時也能省錢、賺錢的小撇步,請記得留到最後!!
Thumbnail
最近開始轉涼了,各位鳥奴們是否會開始擔心小鳥會著涼呢?不用擔心,今天這篇直接帶你看需要的商品,而且今天除了照片之外,我們也直接帶連結✨讓你的雙11購物不盲目,讓你想買直接加入購物車,除了長知識也可以直接下單避寒神器🫱🏼文章結尾也會告訴大家在花錢的同時也能省錢、賺錢的小撇步,請記得留到最後!!
Thumbnail
在 Python 中,print( ) 函數用於將結果輸出到螢幕上。當你嘗試將不同資料型別(例如字串和數字)混合在一起輸出時,print( )函數無法直接處理這些不同型別的資料,因此你需要先將它們轉換為相同的資料型別。通常,這意味著需要將數字轉換為字串型別,以便與其他字串一同輸出。 雖然我們也可以
Thumbnail
在 Python 中,print( ) 函數用於將結果輸出到螢幕上。當你嘗試將不同資料型別(例如字串和數字)混合在一起輸出時,print( )函數無法直接處理這些不同型別的資料,因此你需要先將它們轉換為相同的資料型別。通常,這意味著需要將數字轉換為字串型別,以便與其他字串一同輸出。 雖然我們也可以
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
本文介紹如何用Python繪製散布圖與迴歸線
Thumbnail
本文介紹如何用Python繪製散布圖與迴歸線
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
Thumbnail
設計程式來讀取欲傳送訊息之參數txt檔案,再利用程式自動傳出訊息至LINE群組。能簡易使用於任何場合。
Thumbnail
設計程式來讀取欲傳送訊息之參數txt檔案,再利用程式自動傳出訊息至LINE群組。能簡易使用於任何場合。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News