1. 程式人生 > 實用技巧 >Python網路程式設計

Python網路程式設計

1. socket套接字

1.1 socket簡介

1)網路中的程序間通訊

在本地可以通過程序PID來唯一標識一個程序,但是在網路中這卻是行不通的。

TCP/IP協議族已經解決了這個問題,網路層的“IP地址”可以唯一標識網路中的主機,而傳輸層“協議+埠”可以唯一標識主機中的應用程式(程序)。

這樣利用 IP地址,協議,埠 就可以表示網路中的程序了,網路中的程序通訊就可以利用這個標誌與其他程序進行互動。

2)什麼是socket

socket簡稱套接字,是程序間通訊的一種方式;它能實現不同主機間的程序間通訊。

socket是應用層與TCP/IP協議族通訊中間軟體抽象層,它是一組介面

在設計模式中,socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在socket介面後面,對於使用者來說,一組簡單的介面就是全部,讓socket去組織資料,以符合指定的協議;進而,我們無需去關心TCP/UDP協議的細節,因為socket已經封裝好了,我們只需要遵循socket的規定去程式設計,自然就是遵循tcp/udp標準的。

3)socket層

1.2 套接字的分類

基於檔案型別的套接字家族:AF_UNIX

  • 在泛unix系統上,基於檔案的套接字呼叫的就是底層的檔案系統來取資料,
  • 兩個套接字程序執行在同一機器上,可以通過訪問同一個檔案來間接完成通訊。

基於網路型別的套接字家族:AF_INET

  • 還有AF_INET6被用於ipv6

1.3 套接字的工作流程

1)工作流程圖示

2)工作流程解釋

  • 伺服器端:服務端先初始化socket,然後與埠繫結(bind),對埠進行監聽(listen),再呼叫accept阻塞,等待客戶端連線
  • 客戶端:服務端初始化完畢後,如果有個客戶端初始化一個socket,然後連線伺服器(connect),如果簡連線成功,這時客戶端與服務端的連線就建立了
  • 客戶端與服務端進行互動:客戶端傳送資料請求,服務端接受請求並處理請求,然後把迴應資料傳送給客戶端,客戶端讀取資料,最後關閉連線,一次互動結束

1.4 建立socket

1)建立socket示例

  • socket_family:可以選擇AF_INET或者AF_UNIX
  • socket_type:可以選擇SOCK_STREAM(流式套接字,主要用於TCP協議)或者SOCK_DGRAM(資料報套接字,主要用於UDP協議)
import socket
socket.socket(socket_family,socket_type,protocal=0)
# socket_family 可以是 AF_UNIX 或 AF_INET
# socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM
# protocol 一般不填,預設值為 0

# 獲取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 獲取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 由於 socket 模組中有太多的屬性,在這裡破例使用了'from module import *'語句
# 使用 'from socket import *', 就把 socket 模組裡的所有屬性都帶到我們的名稱空間裡了,這樣能 大幅減短我們的程式碼
# 例如tcpSock = socket(AF_INET, SOCK_STREAM)

2)服務端套接字函式

s.bind()     # 繫結(主機,埠號)到套接字
s.listen()   # 開始TCP監聽
s.accept()   # 被動接受TCP客戶的連線,(阻塞式)等待連線的到來

3)客戶端套接字函式

s.connect()     # 主動初始化TCP伺服器連線
s.connect_ex()  # connect()函式的擴充套件版本,出錯時返回出錯碼,而不是丟擲異常

4)公共用途的套接字函式

s.recv()            # 接收TCP資料
s.send()            # 傳送TCP資料(send在待發送資料量大於己端快取區剩餘空間時,資料丟失,不會發完)
s.sendall()         # 傳送完整的TCP資料(本質就是迴圈呼叫send,sendall在待發送資料量大於己端快取區剩餘空間時,資料不丟失,迴圈呼叫send直到發完)
s.recvfrom()        # 接收UDP資料
s.sendto()          # 傳送UDP資料
s.getpeername()     # 連線到當前套接字的遠端的地址
s.getsockname()     # 當前套接字的地址
s.getsockopt()      # 返回指定套接字的引數
s.setsockopt()      # 設定指定套接字的引數
s.close()           # 關閉套接字

5)面向鎖的套接字方法

s.setblocking()     # 設定套接字的阻塞與非阻塞模式
s.settimeout()      # 設定阻塞套接字操作的超時時間
s.gettimeout()      # 得到阻塞套接字操作的超時時間

6)面向檔案的套接字的函式

s.fileno()          # 套接字的檔案描述符
s.makefile()        # 建立一個與該套接字相關的檔案

2. 基於TCP的套接字