Python Socket 編程
Socket 基本概念
Socket 是對 TCP/IP 協議族的一種封裝,是應用層與TCP/IP協議族通信的中間軟件抽象層。從設計模式的角度看來,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數據,以符合指定的協議。
Socket 還可以認爲是一種網絡間不同計算機上的進程通信的一種方法,利用三元組(ip地址,協議,端口)就可以唯一標識網絡中的進程,網絡中的進程通信可以利用這個標誌與其它進程進行交互。
Socket 起源於 Unix ,Unix/Linux 基本哲學之一就是“一切皆文件”,都可以用打開(open)
-–> 讀寫(write/read)
-–> 關閉(close)
模式來進行操作。因此 Socket 也被處理爲一種特殊的文件。
Socket 編程思想
TCP 服務器
1、創建套接字,綁定套接字到本地IP與端口
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind()
2、開始監聽鏈接
s.listen()
3、進入循環,不斷接受客戶端的鏈接請求
While True:
s.accept()
4、接收客戶端傳來的數據,並且發送給對方發送數據
s.sendall()
5、傳輸完畢後,關閉套接字
s.close()
TCP 客戶端
1、創建套接字並鏈接至遠端地址
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect()
2、鏈接後發送數據和接收數據
s.sendall()
s.recv()
3、傳輸完畢後,關閉套接字
Socket 編程原理圖
Socket 編程實踐之服務器端代碼
#!usr/bin/python
#coding:utf-8
import socket
HOST = '127.0.0.1'
PORT = 8001
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
print("The Server is listening %s:%s"%(HOST,PORT))
while True:#無限循環等待用戶連接
conn,addr = s.accept()
print("connected by ",addr)
while True:#無限循環接收用戶消息
data = conn.recv(1024)
print("client>",data.decode())
msg = 'Server have received your msg'
conn.send(msg.encode())
conn.close()
Socket 編程實踐之客戶端代碼
#!usr/bin/python
# coding:utf-8
import socket
HOST = '127.0.0.1'
PORT = 8001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
while True:
msg = input("please you msg:")
s.send(msg.encode())
data = s.recv(1024)
print(data.decode())
要點
- pyhton3中,數據在網絡中傳輸時,因採用byte類型傳輸,需data.enconde(),傳輸接收後轉化deconde()
如圖:
- 發送數據後,數據被分組發送需要,讓接收端sleep()後接受,可全部接受數據
- 服務器需要兩層循環
附錄
Python 提供了兩個基本的 socket 模塊:
Socket
它提供了標準的BSD Socket API。SocketServer
它提供了服務器重心,可以簡化網絡服務器的開發。
下面講解下 Socket模塊功能
Socket 類型
套接字格式:socket(family, type[,protocal]) 使用給定的套接族,套接字類型,協議編號(默認爲0)來創建套接字
socket 類型 | 描述 |
---|---|
socket.AF_UNIX | 用於同一臺機器上的進程通信(既本機通信) |
socket.AF_INET | 用於服務器與服務器之間的網絡通信 |
socket.AF_INET6 | 基於IPV6方式的服務器與服務器之間的網絡通信 |
socket.SOCK_STREAM | 基於TCP的流式socket通信 |
socket.SOCK_DGRAM | 基於UDP的數據報式socket通信 |
socket.SOCK_RAW | 原始套接字,普通的套接字無法處理ICMP、IGMP等網絡報文,而SOCK_RAW可以;其次SOCK_RAW也可以處理特殊的IPV4報文;此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由用戶構造IP頭 |
socket.SOCK_SEQPACKET | 可靠的連續數據包服務 |
創建TCP Socket:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
創建UDP Socket:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
Socket 函數
- TCP發送數據時,已建立好TCP鏈接,所以不需要指定地址,而UDP是面向無連接的,每次發送都需要指定發送給誰。
- 服務器與客戶端不能直接發送列表,元素,字典等帶有數據類型的格式,發送的內容必須是字符串數據。
服務器端 Socket 函數
Socket 函數 | 描述 |
---|---|
s.bind(address) | 將套接字綁定到地址,在AF_INET下,以tuple(host, port)的方式傳入,如s.bind((host, port)) |
s.listen(backlog) | 開始監聽TCP傳入連接,backlog指定在拒絕鏈接前,操作系統可以掛起的最大連接數,該值最少爲1,大部分應用程序設爲5就夠用了 |
s.accpet() | 接受TCP鏈接並返回(conn, address),其中conn是新的套接字對象,可以用來接收和發送數據,address是鏈接客戶端的地址。 |
客戶端 Socket 函數
Socket 函數 | 描述 |
---|---|
s.connect(address) | 鏈接到address處的套接字,一般address的格式爲tuple(host, port),如果鏈接出錯,則返回socket.error錯誤 |
s.connect_ex(address) | 功能與s.connect(address)相同,但成功返回0,失敗返回errno的值 |
公共 Socket 函數
Socket 函數 | 描述 |
---|---|
s.recv(bufsize[, flag]) | 接受TCP套接字的數據,數據以字符串形式返回,buffsize指定要接受的最大數據量,flag提供有關消息的其他信息,通常可以忽略 |
s.send(string[, flag]) | 發送TCP數據,將字符串中的數據發送到鏈接的套接字,返回值是要發送的字節數量,該數量可能小於string的字節大小 |
s.sendall(string[, flag]) | 完整發送TCP數據,將字符串中的數據發送到鏈接的套接字,但在返回之前嘗試發送所有數據。成功返回None,失敗則拋出異常 |
s.recvfrom(bufsize[, flag]) | 接受UDP套接字的數據u,與recv()類似,但返回值是tuple(data, address)。其中data是包含接受數據的字符串,address是發送數據的套接字地址 |
s.sendto(string[, flag], address) | 發送UDP數據,將數據發送到套接字,address形式爲tuple(ipaddr, port),指定遠程地址發送,返回值是發送的字節數 |
s.close() | 關閉套接字 |
s.getpeername() | 返回套接字的遠程地址,返回值通常是一個tuple(ipaddr, port) |
s.getsockname() | 返回套接字自己的地址,返回值通常是一個tuple(ipaddr, port) |
s.setsockopt(level, optname, value) | 設置給定套接字選項的值 |
s.getsockopt(level, optname[, buflen]) | 返回套接字選項的值 |
s.settimeout(timeout) | 設置套接字操作的超時時間,timeout是一個浮點數,單位是秒,值爲None則表示永遠不會超時。一般超時期應在剛創建套接字時設置,因爲他們可能用於連接的操作,如s.connect() |
s.gettimeout() | 返回當前超時值,單位是秒,如果沒有設置超時則返回None |
s.fileno() | 返回套接字的文件描述 |
s.setblocking(flag) | 如果flag爲0,則將套接字設置爲非阻塞模式,否則將套接字設置爲阻塞模式(默認值)。非阻塞模式下,如果調用recv()沒有發現任何數據,或send()調用無法立即發送數據,那麼將引起socket.error異常。 |
s.makefile() | 創建一個與該套接字相關的文件 |