網(wǎng)絡(luò)通信是現(xiàn)代軟件開發(fā)中不可或缺的一部分,它可以讓不同的設(shè)備之間通過網(wǎng)絡(luò)進行數(shù)據(jù)交換。Python作為一門功能強大、簡潔優(yōu)雅的編程語言,提供了標準庫socket,用于實現(xiàn)底層的網(wǎng)絡(luò)通信功能。本文將介紹Python中如何使用socket編程,以及給出一個簡單的客戶端和服務(wù)器之間通信的代碼案例。
socket是一種抽象的數(shù)據(jù)結(jié)構(gòu),它表示一個網(wǎng)絡(luò)連接的端點。每個socket都有一個地址和一個端口號,用于標識網(wǎng)絡(luò)中的一個唯一的位置。socket可以分為兩種類型:流式socket(stream socket)和數(shù)據(jù)報式socket(datagram socket)。流式socket基于TCP協(xié)議,提供了可靠、有序、雙向的字節(jié)流傳輸服務(wù),適用于需要穩(wěn)定傳輸?shù)膱鼍埃缥募鬏敗⑦h程登錄等。數(shù)據(jù)報式socket基于UDP協(xié)議,提供了無連接、不可靠、無序的數(shù)據(jù)包傳輸服務(wù),適用于需要快速傳輸?shù)膱鼍?,如視頻通話、在線游戲等。
Python中使用socket編程的基本步驟如下:
- 導(dǎo)入socket模塊:
import socket
- 創(chuàng)建socket對象:
s = socket.socket(family, type)
,其中family指定地址族,如socket.AF_INET
表示IPv4地址,type指定socket類型,如socket.SOCK_STREAM
表示流式socket。 - 綁定地址和端口:
s.bind((host, port))
,其中host是一個字符串,表示主機名或IP地址,port是一個整數(shù),表示端口號。 - 監(jiān)聽連接(僅服務(wù)器端):
s.listen(backlog)
,其中backlog是一個整數(shù),表示最大等待連接數(shù)。 - 接受連接(僅服務(wù)器端):
conn, addr = s.accept()
,其中conn是一個新的socket對象,用于與客戶端通信,addr是一個元組,表示客戶端的地址和端口。 - 發(fā)送數(shù)據(jù):
s.send(data)
或s.sendall(data)
,其中data是一個字節(jié)對象,表示要發(fā)送的數(shù)據(jù)。send方法可能只發(fā)送部分數(shù)據(jù),sendall方法保證發(fā)送所有數(shù)據(jù)。 - 接收數(shù)據(jù):
data = s.recv(bufsize)
,其中bufsize是一個整數(shù),表示接收緩沖區(qū)的大小,data是一個字節(jié)對象,表示接收到的數(shù)據(jù)。 - 關(guān)閉socket:
s.close()
。
下面給出一個簡單的客戶端和服務(wù)器之間通信的代碼案例:
服務(wù)器端:
import socket
# 創(chuàng)建流式socket對象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定本機地址和端口8080
s.bind(('localhost', 8080))
# 監(jiān)聽最多10個連接
s.listen(10)
print('服務(wù)器啟動成功,等待客戶端連接...')
# 循環(huán)接受客戶端連接
while True:
# 接受一個客戶端連接
conn, addr = s.accept()
print('收到來自{}的連接'.format(addr))
# 循環(huán)接收和發(fā)送數(shù)據(jù)
while True:
# 接收客戶端發(fā)送的數(shù)據(jù)
data = conn.recv(1024)
# 如果沒有數(shù)據(jù),則跳出循環(huán)
if not data:
break
# 打印接收到的數(shù)據(jù)
print('收到來自{}的消息:{}'.format(addr, data.decode()))
# 將接收到的數(shù)據(jù)原樣返回給客戶端
conn.sendall(data)
# 關(guān)閉連接
conn.close()
print('與{}斷開連接'.format(addr))
# 關(guān)閉socket
s.close()
客戶端:
import socket
# 創(chuàng)建流式socket對象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連接服務(wù)器地址和端口8080
s.connect(('localhost', 8080))
print('成功連接服務(wù)器')
# 循環(huán)發(fā)送和接收數(shù)據(jù)
while True:
# 輸入要發(fā)送的數(shù)據(jù)
data = input('請輸入要發(fā)送的消息:')
# 如果輸入空字符串,則跳出循環(huán)
if not data:
break
# 將數(shù)據(jù)編碼為字節(jié)對象
data = data.encode()
# 發(fā)送數(shù)據(jù)給服務(wù)器
s.sendall(data)
# 接收服務(wù)器返回的數(shù)據(jù)
data = s.recv(1024)
# 打印接收到的數(shù)據(jù)
print('收到來自服務(wù)器的消息:{}'.format(data.decode()))
# 關(guān)閉socket
s.close()
更多python課程推薦python相關(guān)課程