「Python網絡編程」進入網絡通信編程的大世界(一)

博主前言:

寒假在家待着實屬無聊,所以準備繼續跟博,本來想搞一個什麼“十天搞定Python網絡編程”、“一週Python網絡編程入門大法”等等,但是在整理完資料開始寫的時候才發現這些搏眼球的招數都被全網用遍了,倒不如實實在在寫一些東西。開寫網絡編程系列呢,需要讀者已經瞭解了Python語言的語言邏輯和具有使用Python編程的基礎,這方面的知識網上也挺多的,所以博主來這裏就不在繼續講解,如果有地方不懂的可以留言,我會及時的回覆噠。

1. 幾個網絡編程重要概念

1.1 IP地址

首先我們要知道網絡編程的目的是爲了進行通信,所以IP地址可以理解爲不同電腦在網絡中的標識定位,只有知道IP地址才能準確的定位對方的電腦進行通信。

1.1.1 IP地址的分類

IP地址分爲兩大類:IPv4IPv6
其中IPv4又分爲A、B、C、D、E五類地址。

A類地址:0 + 網絡號7位 + 主機號24位
B類地址:10 + 網絡號14位 + 主機號16位
C類地址:110 + 網絡號21位 + 主機號8位
D類地址:保留地址,網絡號由1110開頭
E類地址:保留地址,網絡號由11110開頭

其中主機號全是0和全是1的地址用不了,所以一個C類地址的IP地址,網絡號確定時,其最多定義254臺電腦。
最後注意:IP地址爲127.0.0.1127.255.255.255用於迴環測試

1.2 端口號

端口號是用來標識進程的值。這裏引入的一個進程的概念,很簡單,所謂進程就是運行着的程序,我們打開任務管理器,如圖所示。
這裏爲什麼我們用進程,而不是程序呢,因爲在列表中都是運行着的程序啦。很簡單吧。
在這裏插入圖片描述
如果把IP地址比作你家的房子的地址,那端口號就是你家裏的成員的名字。當發生網絡通信的時候,通過你家的地址,找到你家,然後通過你們家裏人的名字確認與家裏的誰進行通信。也就是,通過IP地址確認主機電腦,再通過端口號確認與電腦裏哪一個程序進行通信的過程。
我們再來了解兩個關於端口號的概念。

1.2.1 端口號的分類

第一類叫知名端口,又稱周知端口,兩個詞指的是同一個概念,即值從0~1023的端口號,共1024個端口號。這些端口號都被預先使用了,我們編寫程序是不能使用的,所以叫做知名端口或周知端口。例如:端口號爲80指的HTTP服務;端口號爲21指的FTP服務等
第二類叫動態端口,即值從1024~65535的端口號。動態端口,顧名思義,其值是動態分配的。當我們開發一個程序時,其端口號值由開發者去綁定。亦或當開發者沒有綁定時,系統默認給你動態分配一個值,例如QQ。

2. 套接字Socket模塊

Socket是進程間通信的一種方式,可以實現不同主機間的進程間通信。衆所周知,網絡通信有兩種方法,一種是基於TCP協議的通信方法,另一種是基於UDP協議的通信方法。所以Python的Sockert模塊針對兩種不同的方法有兩種說明。接下來我們就let it down,開始我們迷人又可愛的編程!

2.1 創建一個UDP Socket

import socket
def main():
    # 建立udp對象,第一個參數是 使用ipv4協議 第二個參數是 使用 udp 協議
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    # 綁定一個端口號
    localaddr = ("",1314)
    udp_socket.bind(localaddr)
    # 輸入你想發送的數據
    send_Data = "給你1個G"
    # 發送數據,以 udp 的方式,第二參數是一個元組,包含目標ip和端口號
    udp_socket.sendto(send_Data.encode("utf-8")("127.0.0.1",6666))
    print("發送成功!")
    # 關閉套接字
    udp_socket.close()
if __name__ =='__main__':
    main()

通過上面的代碼我們就實現了創建一個基於UDP協議的Socket對象,並進行向IP地址爲“127.0.0.1”(迴環測試),端口號爲6666的程序發送數據。
首先,我們用socket模塊的構造方法創建一個UDP對象,構造方法中有兩個參 數,第一個參數代表使用IPv4協議,第二個參數代表使用UDP協議。
然後,我們將創建好的Socket對象綁定一個端口號,使用bind函數,函數第一個參數是IP地址,默認爲本機的任一IP地址,第二個參數爲端口號。
接着,我們調用sendto函數,向目的IP地址及端口發送數據,發送函數的第一個參數爲發送的數據,其類型爲bytes類型,其中我們選擇使用utf-8的格式進行編碼,第二個參數爲一個元組類型,其包含了目的主機的IP地址和目的程序的端口號。
最後,調用close函數,關閉套接字。

我們使用網絡調試助手模擬上述步驟,將在網絡調試助手的界面得到以下圖示。
在這裏插入圖片描述

2.2 創建一個TCP Socket

TCP通信模型相比UDP通信模型更加穩定,可靠。因爲TCP通信模型在數據發送之前有創建連接的步驟(俗稱:三次握手),並在數據發送階段有ACK、超時重傳(RTT)、錯誤校驗、流量控制和阻塞管理等加強通信模型可靠性的措施,所以TCP通信模型運用得更加普遍。

import socket
def main():
    # 1.創建 tcp 套接字
    tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2.鏈接服務器
    tcp_socket.connect(("127.0.0.1",1314))
    # 3.發送數據
    data = input("Input the data what you want to send:")
    tcp_socket.send(data.encode("utf-8"))
    # 4.關閉套接字
    tcp_socket.close()

if __name__ == '__main__':
    main()

同樣,我們通過上述代碼創建了一個基於TCP的Socket對象,並與IP地址爲“127.0.0.1”,端口號爲1314的服務器程序進行鏈接。然後通過input函數從鍵盤上獲得需要發送的數據,並調用send函數以utf-8的格式發送數據,最後關閉套接字。

在這裏不禁提出一個問題,在創建UDP Socket對象時,我們還調用了bind函數,綁定一個IP地址和端口號,爲什麼在創建TCP Socket對象的時候,我們沒有使用bind函數去綁定呢?使用bind函數是必須的嗎?

我們再次利用網絡調試助手進行步驟演示,以網絡調試助手爲服務器,代碼運行作爲客戶端。在這裏插入圖片描述代碼運行客戶端
我們從對端口號的學習中知道,當開發者沒有綁定端口號,程序運行時,系統會默認給它分配一個動態端口用以通信,例如上圖網絡調試助手中的51383,就是系統爲此進程默認分配的動態端口。所以,當確認程序只進行發送操作而不進行接收操作時,程序可以不進行綁定操作,但是若程序需要進行接收操作時,沒有綁定端口號,發送方將無法得知接收方的地址,無法成功進行接收操作。

好了,第一篇算是完成了,其中乾貨也是滿滿呀,希望讀者好好消化吸收,如果有不懂的地方一定留言交流,想想下一篇寫什麼吶?多線程?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章