上篇:
socket程式設計
什麼是socket?
簡稱套接字,是程序間通訊的一種方式,它與其他程序間通訊的乙個主要不同是:它能實現不同主機
間的程序間通訊,我們網路上各種各樣的服務大多數是基於socket來完成通訊的。
socket是基於c/s架構的,也就是說socket網路程式設計,通常需要寫兩個檔案,乙個服務端,乙個客戶端
python中的socket通訊邏輯如下圖所示
在python中,用socket.socket()方法來建立套接字
s = socket.socket([family[, type[, proto]]])
引數說明:
family:套接字家族,可以使用af_unix或者af_inet
type:套接字型別,分為sock_stream或者sock_dgram,分別代表tcp和udp
protocol: 一般不填預設為0
注意1.python3以後,socket傳遞的都是bytes型別的資料,字串需要先轉換一下,string.encode()即可;另一端在接收資料的時候需要bytes轉換成字串,只要bytes.decode()一下就可以
2.在正常通訊時,accept()和recv()方法都是阻塞的。所謂的阻塞,指的是程式會暫停在哪,一直等資料過來
socket程式設計思路
1 建立套接字,繫結套接字到本地ip與埠:socket.socket(scoket.af_inet,socket.sock_stream), s.bind()
3 進入迴圈,不斷接受客戶端的鏈結請求:s.accept()
4 接收傳來的資料,或者傳送資料給對方:s.recv() , s.sendall()
5 傳輸完畢後,關閉套接字:s.close()
客戶端2 連線後傳送資料和接收資料: s.sendall(),s.recv()
3 傳輸完畢後,關閉套接字:s.close()
python的socket程式設計,通常可以分為tcp和udp程式設計兩種,前者是連線的可靠傳輸服務,每次通訊都要握手,結束傳輸也要揮手,資料會被檢驗,是使用最廣的通用模式;後者是不帶連線的傳輸服務,簡單粗暴
伺服器端:
import socketip_port = ('127.0.0.1', 9999)
sk = socket.socket() # 建立套接字
sk.bind(ip_port) # 繫結服務位址
sk.listen(5) # 監聽連線請求
print('啟動socket服務,等待客戶端連線...')
conn, address = sk.accept() # 等待連線,此處自動阻塞
while true: # 乙個死迴圈,直到客戶端傳送『exit』的訊號,才關閉連線
client_data = conn.recv(1024).decode() # 接收資訊
if client_data == "exit": # 判斷是否退出連線
exit("通訊結束")
print("來自%s的客戶端向你發來資訊:%s" % (address, client_data))
conn.sendall('伺服器已經收到你的資訊'.encode()) # 回饋資訊給客戶端
conn.close() # 關閉連線
客戶端:
import socket
ip_port = ('127.0.0.1', 9999)
s = socket.socket() # 建立套接字
s.connect(ip_port) # 連線伺服器
while true: # 通過乙個死迴圈不斷接收使用者輸入,並傳送給伺服器
inp = input("請輸入要傳送的資訊: ").strip()
if not inp: # 防止輸入空資訊,導致異常退出
continue
s.sendall(inp.encode())
if inp == "exit": # 如果輸入的是『exit』,表示斷開連線
print("結束通訊!")
break
server_reply = s.recv(1024).decode()
print(server_reply)
s.close() # 關閉連線
雖然伺服器和客戶端在一對一的情況下,工作良好,但是,如果有多個客戶端同時連線同乙個伺服器呢?結果可能不太令人滿意,因為伺服器無法同時對多個客戶端提供服務。為什麼會這樣呢?因為python的socket模組,預設情況下建立的是單程序單執行緒,同時只能處理乙個連線請求,如果要實現多使用者服務,那麼需要使用多執行緒機制
import socket
import threading
def link_handler(link,clinet):
print("伺服器開始接收來自%s:%s的請求" %(clinet[0],clinet[1]))
while true:
# 解碼為bytes
clinet_data= conn.recv(1024).decode()
if clinet_data== 'exit':
print('通訊結束')
break
print("來自%s的客戶端向伺服器發來資訊: %s"%(clinet,clinet_data))
conn.sendall("伺服器已經接收到你的資訊了".encode())
ip_port= ('127.0.0.1',9999)
s= socket.socket()
s.bind(ip_port)
s.listen(5)
print('啟迪socket服務,等待客戶端連線...')
while true:
conn,address= s.accept()
t= threading.thread(target=link_handler,args=(conn,address))
t.start()
Python網路程式設計學習筆記一 socket模組
coding utf 8 主要測試python網路程式設計中socket模組的使用 涉及到的技術點 套接字 面向連線的還有非面向連線套接字 tcp面向連線 udp非面向連線 1 匯入socket 2 建立socket socket三要素 1 socket family,2 socket type 3...
python 網路程式設計學習 套接字socket
以前也學過套接字程式設計,這次想系統全面的學習下python網路程式設計的使用。做這個,為檢測進度,也為後續留下筆記和足跡。socket 常用函式 socket.gethostname socket.gethostbyname import socket host socket.gethostnam...
Python之非同步IO模型實現socket併發
服務端 import socket sk socket.socket addr 127.0.0.1 8090 sk.bind addr sk.listen sk.setblocking false 設定非阻塞模式,accept,recv等方法均不阻塞,而是丟擲異常 conn lst 建立乙個列表儲存...