Python Socket 網路通訊教學

本篇 ShengYu 介紹如何寫 Python Socket 網路通訊程式,在這個網路盛行的時代,網路通訊已成為基礎,想要精通學習網路通訊必須先了解 TCP/IP 協定,其中以 TCP 與 UDP 兩種主要通訊方式最常被使用,接下來教學內容將介紹如何使用 Python Socket API 來搭建一個典型的 TCP & UDP 通訊程式,甚至可以寫出一個聊天室的程式,或者像 LINE 或 Skype 這樣的通訊程式。

以下 Python Socket 教學內容將分為幾部分,分別為:

  • Python Socket TCP Server & Client 基本範例
  • Python Socket UDP Server & Client 基本範例

在 Python 中已經內建好 Socket API 供你使用,所以不需另外安裝額外的套件即可使用,接下來我們就來看看 Python Socket TCP Server 與 Client 的程式怎麼撰寫吧!

Python Socket TCP Server & Client 基本範例

這邊介紹 Python Socket TCP 伺服器端與客戶端的網路通訊程式,TCP 這種連線協議具有可靠性,因為 TCP 協議有重傳的機制,所以收到的封包一定沒有錯誤,也因為 TCP 協議的關係在傳輸速度上會有所犧牲,在稍後會介紹 UDP 無重傳機制,提升傳輸性能,不過 TCP 還是給我們帶來很大的便利性,一般瀏覽網頁的 HTTP 協議就是基於 TCP 的基礎,接下來示範一下簡單的 Python Socket TCP Server 伺服器端程式,

如下例所示,伺服器端一開始建立 socket,socket.AF_INET 表示使用 Internet Protocol 的通訊協定,而 socket.SOCK_STREAM 表示傳輸方式為 TCP,用 bind() 綁定,這裡是使用 0.0.0.0, port 為 7000

使用 listen() 開始監聽,上限連線數為5,之後進入主迴圈,accept() 等待接受客戶端的連線請求,一旦有客戶端連線的話,就會從 accept() 繼續往下執行,

接著從這個連線 recv() 接收資料與 send() 傳送資料,之後就關閉該連線,之後回到 accept() 等待新的客戶端連線,等到新的客戶端連線連上便跟之前的流程一樣,這樣便是一個完整的 Python Socket TCP 伺服器程式。

python3-socket-tcp-server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket

HOST = '0.0.0.0'
PORT = 7000

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)

print('server start at: %s:%s' % (HOST, PORT))
print('wait for connection...')

while True:
conn, addr = s.accept()
print('connected by ' + str(addr))

indata = conn.recv(1024)
print('recv: ' + indata.decode())

outdata = 'echo ' + indata.decode()
conn.send(outdata.encode())
conn.close()
s.close()

下面範例是對應的 Python Socket TCP Client 客戶端端程式,如下例所示,客戶端一開始建立 socket,之後 connect() 連線伺服器主機的 host 與 port,
接著使用 send()'hello tcp' 字串發送給伺服器端,然後使用 recv() 接收來至伺服器端的資料,接收到資料後就把它印出來,之後就關閉該連線,

python3-socket-tcp-client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket

HOST = '0.0.0.0'
PORT = 7000

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

outdata = 'hello tcp'
print('send: ' + outdata)
s.send(outdata.encode())

indata = s.recv(1024)
print('recv: ' + indata.decode())

s.close()

先執行 TCP 伺服器端程式等著,接著再執行 TCP 客戶端端程式就可以將此範例完整體驗,TCP 伺服器端的輸出如下,

1
2
3
4
5
$ python3 python3-socket-tcp-server.py
server start at: 0.0.0.0:7000
wait for connection...
connected by ('127.0.0.1', 42202)
recv: hello tcp

TCP 客戶端的輸出如下,

1
2
3
$ python3 python3-socket-tcp-client.py 
send: hello tcp
recv: echo hello tcp

以上是最基本的 Python Socket TCP 用法與範例,本篇僅示範客戶端傳送一次資料便關閉連線,詳細的 Python Socket TCP 通訊程式範例可以參考 Python TCP Socket Server/Client 網路通訊教學這篇,裡面還會介紹伺服器端如何對同一客戶端多次通訊,以及客戶端如何不間斷地跟伺服器端溝通。

Python Socket UDP Server & Client 基本範例

這邊介紹 Python Socket UDP 服器端與客戶端的網路通訊程式,UDP 無重傳機制,所以相對於 TCP 來說是傳輸效率較好,但因為不保證資料正確性的關係,意味著必須自己實作資料檢查機制,接下來示範一下簡單的 Python Socket UDP Server 伺服器端程式,

如下例所示,伺服器端一開始建立 socket,socket.AF_INET 表示使用 Internet Protocol 的通訊協定,而 socket.SOCK_DGRAM 表示傳輸方式為 UDP,用 bind() 綁定,這裡是使用 0.0.0.0, port 為 7000

跟 TCP 不同的是 UDP 不需使用 listen()accept(),直接使用 recvfrom 來接收任何一個 socket 地址的客戶端資料,以及 sendto 傳送資料給指定 socket 位址的客戶端,這邊用一個迴圈不斷地重複 recvfrom() 接收資料與 sendto() 傳送資料,這樣便是一個完整的 Python Socket UDP 伺服器程式。

python3-socket-udp-server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket

HOST = '0.0.0.0'
PORT = 7000

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((HOST, PORT))

print('server start at: %s:%s' % (HOST, PORT))
print('wait for connection...')

while True:
indata, addr = s.recvfrom(1024)
print('recvfrom ' + str(addr) + ': ' + indata.decode())

outdata = 'echo ' + indata.decode()
s.sendto(outdata.encode(), addr)
s.close()

下面範例是對應的 Python Socket UDP Client 客戶端端程式,如下例所示,客戶端一開始建立 socket,跟 TCP 不同的是 UDP 不需要 connect() 而是直接用 sendto() 將資料送往指定的主機 host 與 port,
接著使用 sendto()'hello udp' 字串發送給伺服器端,然後使用 recvfrom() 接收來至伺服器端的資料,接收到資料後就把它印出來,之後就關閉該連線,

python3-socket-udp-client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket

HOST = '0.0.0.0'
PORT = 7000
server_addr = (HOST, PORT)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

outdata = 'hello udp'
print('sendto ' + str(server_addr) + ': ' + outdata)
s.sendto(outdata.encode(), server_addr)

indata, addr = s.recvfrom(1024)
print('recvfrom ' + str(addr) + ': ' + indata.decode())

先執行 UDP 伺服器端程式等著,接著再執行 UDP 客戶端端程式就可以將此範例完整體驗,TCP 伺服器端的輸出如下,

1
2
3
4
$ python3 python3-socket-udp-server.py 
server start at: 0.0.0.0:7000
wait for connection...
recvfrom ('127.0.0.1', 44346): hello udp

UDP 客戶端的輸出如下,

1
2
3
$ python3 python3-socket-udp-client.py
sendto ('0.0.0.0', 7000): hello udp
recvfrom ('127.0.0.1', 7000): echo hello udp

以上是最基本的 Python Socket UDP 用法與範例,本篇僅示範客戶端傳送一次資料便關閉連線,詳細的 Python Socket UDP 通訊程式範例可以參考 Python UDP Socket Server/Client 網路通訊教學這篇,裡面還會介紹伺服器端如何對同一客戶端多次通訊,以及客戶端如何不間斷地跟伺服器端溝通。

以上就是 Python Socket 網路通訊教學介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其他參考
socket — Low-level networking interface — Python 3 documentation
https://docs.python.org/3/library/socket.html

其它相關文章推薦
Python 新手入門教學懶人包