一、什麼網路通訊
計算機網路把分佈在不同地理區域的計算機與專門的外部裝置用通訊線路互聯成一個規模大、功能強的網路系統,從而使眾多的計算機可以方便的互相傳遞資訊、共享硬體、軟體、資料資訊等資源。網路程式設計直接或間接地透過網路協議與其它計算機實現資料交換,進行通訊。
OSI參考模型 | TCP/IP參考模型 | TCP/IP參考模型各層對應協議 |
---|---|---|
應用層 | 應用層 | HTTP、FTP、Telnet、DNS…… |
表示層 | ||
會話層 | ||
傳輸層 | 傳輸層 | TCP、UDP…… |
網路層 | 網路層 | IP、ICMP、ARP…… |
資料鏈路層 | 物理+資料鏈路層 | Link |
物理層 |
二、IP和埠號
在通訊時,通訊雙方必須知道對方的標識。網際網路上每個計算機的唯一標識就是 IP 地址。IP 地址實際上就是一個 32 位整數(IPv4),它是以字串表示的 IP 地址。
IP 協議負責把整個資料從一臺計算機透過網路傳送到另一臺計算機。資料被分割成一小塊一小塊,然後透過 IP 包傳送出去。由於網際網路鏈路複雜,兩臺計算機之間經常有多條線路,因此,路由器就負責決定如何把一個 IP 包轉發出去。IP 包的特點就是按快傳送,途徑多個路由,但不保證都能到達,也不能保證順序到達。
- IP地址:InetAddress
- 唯一的標識 Internet 上的計算機(通訊實體)
- 本地迴環地址(hosAddress):127.0.0.1 主機名(hostName):localLost
- IP地址分類方式1:IPV4 和 IPV6
- IPV4:4個位元組組成,大概42億,其中 30 億大概在北美,亞洲 4 億。2011 年已經用盡。以點分十進位制表示
- IPV6:128位(16個位元組),寫成 8 個無符號整數,每個整數用四個十六進位制位標識,數之間用冒號分開
- IP地址分類方式2:公網地址(全球資訊網使用)和 私有地址(區域網使用)
- 192.168. 開頭的就是 私有地址,範圍即為 192.168.0.0 ~ 192.168.255.255,專門為組織機構內部使用
- 埠號:標識正在計算機上執行的程序(程式)
- 不同的程序有不同的埠號
- 被規定為 16 位的整數 0~65535
- 埠分類:
- 公認埠:0~1023。被預先定義的服務通訊佔用
- 註冊埠:1024~49151。分配給使用者程序或應用程式
- 動態/私有埠:49152~65535
- 埠號與 IP 地址的組合得出一個網路套接字:Socket
三、Socket套接字
為了讓兩個程式透過網路進行通訊,二者均必須使用 Socket 套接字。Socket 的英文原義是 “孔” 或 “插座”,通常也稱作為 “套接字”,它用於描述 IP 地址和埠號,它是一個通訊鏈的控制代碼,可以用來實現不同虛擬機器或不同計算機之間的通訊。在 Internet 上的主機上一般執行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個 Socket,並繫結到一個埠上,不同的埠對應於不同的服務。
在 Python 中使用 socket 模組的 socket() 函式進行網路套接字程式設計。
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
函式 socket.socket() 建立一個 socket,它返回該 socket 的描述符,引數說明如下:
- family: 可以選擇 AF_INET(用於 Internet 程序間通訊)或者 AF_UNIX(用於同一機器程序間通訊);
- type: 套接字型別,可以是 SOCK_STREAM(流式套接字,主要用於 TCP 協議)或者 SOCK_DGRAM(資料包套接字,主要用於 UDP 協議)
建立完成後,生成一個 socket 物件,socket 物件的主要屬性和方法如下:
【1】、資料屬性
socket.family # 套接字家族
socket.type # 套接字型別
socket.proto # 套接字協議
【2】、伺服器套接字方法
socket.bind(address) # 將地址(主機名、埠號對)繫結到套接字上
socket.listen([backlog]) # 設定並啟動TCP監聽器
socket.accept() # 被動接收TCP客戶端連線,一直等待直到連線到達(阻塞)
【3】、客戶端套接字方法
socket.connect(address) # 主動發起TCP伺服器連線
socket.connect_ex(address) # connect的擴充套件版本,此時會以錯誤碼形式返回問題,而不是丟擲一個異常
【4】、普通的套接字方法
socket.recv(bufsize[, flags]) # 接收TCP訊息
socket.recv_into(buffer[, nbytes[, flags]]) # 接收TCP訊息到指定的緩衝區
socket.send(bytes[, flags]) # 傳送TCP訊息
socket.sendall(bytes[, flags]) # 完整的傳送TCP訊息
socket.recvfrom(bufsize[, flags]) # 接收UDP訊息
socket.recv_into(buffer[, nbytes[, flags]]) # 接收的UDP訊息到指定的緩衝區
socket.sendto(bytes[, flags], address) # 傳送UDP訊息
socket.getpeername() # 連線到套接字(TCP)的遠端地址
socket.getsockname() # 當前套接字地址
socket.getsockopt(level, optname[, buflen]) # 返回給定套接字選項的值
socket.setsockopt(level, optname, value) # 設定給定套接字選項的值
socket.shutdown(how) # 關閉連線
socket.close(fd) # 關閉套接字
socket.detach() # 在未關閉檔案描述符的情況下關閉套接字,返回檔案描述符
socket.ioctl(control, option) # 控制套接字模式(僅支援Windows)
【5】、面向阻塞的套接字方法
socket.setblocking(flag) # 設定套接字的阻塞或者非阻塞模式
socket.settimeout(value) # 設定阻塞套接字操作的超時時間
socket.gettimeout() # 獲取阻塞套接字操作的超時時間
【6】、面向檔案的套接字方法
socket.fileno() # 套接字的檔案描述符
socket.makefile(mode='r', buffering=None, *, encoding=None, errors=None, newline=None) # 建立與套接字關聯的檔案物件
四、網路協議
計算機網路中實現通訊必須有一些規定,即通訊協議,對速率、傳輸程式碼、程式碼結構、傳輸控制步驟、出錯控制等指定標準。在指定協議時,把複雜成份分解成一些簡單的份,在將它們複合起來。最常用的複合方式是層次方式,即 同層間可以通訊、上一層可以呼叫下一層,而與下一層不發生關係。各層互不影響,利於系統的開發和擴充套件。
- 傳輸層協議中有兩個重要的協議:
- 傳輸控制協議 TCP(Transmission Control Protocol)
- 使用 TCP 協議前,須建立 TCP 連線,形成傳輸資料通道
- 傳輸前,採用“三次握手”的方式,點對點通訊、是可靠的
- TCP 協議進行通訊的兩個應用程序:客戶端、服務端
- 在連線中可進行大資料量的傳輸
- 傳輸完畢,需釋放已建立的連線,效率低
- 使用者資料包協議 UDP(User Datagram Protocol)
- 將資料、源、目的封裝成資料包,不需要建立連線
- 每個資料包的大小限制在 64K 內
- 傳送不斷對方是否準備好,接收方收到也不確認,故是不可靠的
- 可以廣播傳送
- 傳送資料結束時無需釋放資源,開銷小,速度快
- 傳輸控制協議 TCP(Transmission Control Protocol)
- 網路互聯協議 IP(Internet Protocol)是網路層的組要協議,支援網間互聯的資料通訊
- TCP/IP 協議模型從更使用的角度出發,形成了高效的四層體系結構,即 物理鏈路層、IP層、傳輸層 和 控制層;