💻 在同一台電腦上讓程式互通:TCP/IP Socket 原理與實作
🧠 一、為什麼同一台電腦也能用 TCP/IP 通訊?
很多人以為 TCP/IP 只用在「跨網路」的通訊,其實不然。
TCP/IP 是一種協定(Protocol),而非實體連線。
Windows、macOS、Linux 都有「網路堆疊(Network Stack)」模組,當兩個程式使用 TCP/IP 時,它們其實透過作業系統內部的「回送介面(Loopback Interface)」來交換資料。
成果畫面

這個介面對應的 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→ 使用 IPv4socket.SOCK_STREAM→ 使用 TCPbind()綁定 IP 與 Portlisten()等待連線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














