python网络通信框架_Python运维-Socket网络编程 (1)
Python socket 簡介
在計算機通信領域,socket 被翻譯為“套接字”,它是計算機之間進行通信的一種約定或一種方式。通過 socket 這種約定,一臺計算機可以接收其他計算機的數據,也可以向其他計算機發送數據
套接字是通信的基石,是支持TCP/IP協議的路通信的基本操作單元。Socket(套接字)可以看成是兩個網絡應用程序進行通信時,各自通信連接中的端點,這是一個邏輯上的概念。
網絡世界一切皆 socket。如果我們精通 socket?又 熟悉 應用層的高層協議. 那我們就可以通過socket連接網絡世界中的一切。
黑客不需要網絡網絡編程知識?框架這么多何必自己實現?
網絡一直都是黑客最喜愛的競技場. 通過簡單的網絡訪問,攻擊者可以做到任何事情。例如主機掃描、數據包注入、數據嗅探、遠程攻擊主機,等等。如果通過某種方式進入了目標企業的內部網絡,那么在這個陌生的環境中,你可能會發現主機陷入了某種困境: 你沒有任何工具進行網絡攻擊,沒有natcat, 沒有wireshark,沒有編譯器,甚至沒有辦法安裝編譯器。然而在很多情況下,你可能會驚訝地發現目標環境中安裝了Python,這就是下一步的工作起點, 不僅是黑客, 我們的網絡管理員、機房管理員,在某些情況下也會用到。
Python socket 模塊可以快速創建 TCP 和 UDP服務器及客戶端
TCP 客戶端
在滲透測試中我們經常會遇到需要創建一個TCP客戶端來連接服務、發送垃圾數據、進行模糊測試或者進行其他任務的情況。多說無益,我們開始編寫代碼。
① 首先我們創建一個套接字, 你可能會發現我沒有使用參數選擇協議 AF_INET 和類型 SOCK_STREAM. 因為它默認 AF_INET 表示的IPv4地址, 類型是 SOCK_STREAM說明這是一個TCP客戶端。 ② 連接到目標地址和端口, 該方法接受一個元組 (IPAddress, Port) 建立連接失敗是回拋出異常,? 建立連接成功后我們就可以收發數據了。 ③ 使用 send() 方法發送數據注意是字節流數據, byte, 可以使用 encode() 方法將字符串類型 轉為 字節類型。④ 使用 recv() 方法接受數據具體大小根據你傳入的參數大小決定。 單位是字節。接受的數據是字節流數據,可以使用 decode() 方法將字節類型轉為字符串類型。⑤ 程序不用了就關閉連接
TCP 服務器
用 Python 創建 TCP 服務端和創建客戶端一樣簡單。我們可以綁定到命令行 shell 或者創建一個代理(后續)。加下來我們創建一個TCP服務器
① 綁定監聽地址和端口 ② 設置最大掛起連接等待數,③ 接受連接,該方法返回兩個結果 遠程(客戶端)套接字對象, 遠程(客戶端)連接地址和端口(阻塞方法),④ 接受客戶端數據, 注意這里是阻塞的(客戶端沒法信息就會一直等等到又信息才會往下執行),⑤ 發送數據,該方法也會阻塞如果客戶端一直沒有接受也會一直阻塞
執行結果
客戶端和服務端都編寫完成了我們先允許服務端 再允許客戶端看一下結果
服務端
客戶端
運行沒有問題, 他們可以互相通訊了。
問題
運行是可以運行了但是,服務器和客戶端一次鏈接只能交換一次數據,非常不符合現在服務器的標準。可以這么解決呢??? 上面提到有三個阻塞的方法. accept()、send()、recv()。這三個方法都是先等對方有相應的行為才會往下執行。回產生上面問題呢?? 我們一 一解決, 如果中間覺得繁瑣可以跳到最終解決方法
解決只能通訊一次(保持連接)
現在的連接叫 短連接,即數據交換完成之后立刻斷開連接. 目前在使用短連接的大家都熟悉的 HTTP 通訊協議
客戶端
代碼邏輯幾乎沒變, ① while True進入循環 ② 接受用戶輸入(阻塞方法), ③ 判斷用戶是否輸入 exit() 退出循環, 關閉連接。然后發送數據, 接受響應. 打印響應信息,循環進行。
服務器
大致邏輯也沒變, ① 連接成功后進入循環, ② 接受客戶端數據 ③ 如果接受到 exit() 退出循環關閉連接。循環操作。
服務端的發送(響應)數據也可以 加上 input監聽用戶輸入, 這樣就可以實現 半雙工通訊了 即同一時間段只有一邊可以發送數據另外一邊接受數據。例子: 對講機
我們來看一下執行結果
客戶端
服務器
長連接通訊就完成了, 我們只要不主動斷開連接就可以一直交換數據, 但是還存在上面問題呢...
我們來將一下整套程序的流程, 服務器開啟監聽服務. 客戶端連接, 連接成功后 服務器和客戶端進入循環, 互相通訊, 直到程序退出 才斷開連接。看似沒什么問題呀... 但你會發現 第二個人想嘗試連接這個服務器時... 連接是沒報錯 但也沒執行到 while True 可以交換信息.
原因是我們的服務器沒把 accept 寫到循環里(我的意料之外...我也忘記了)如果寫道循環里大家想想. accept 是阻塞.. 那就套兩層循環. 對套兩層循環 下面這樣
這樣就會出現剛剛的問題了 連接上了但是服務器沒有處理我的連接, 因為他在處理上一個客戶端的連接, 服務器此時處于忙碌狀態。
為什么連接成功了呢?因為我們設置了 Listen(5) 最大掛起等待連接數 5, (意思是當服務器忙碌時能有多少臺客戶端在排隊等待). 你把他設低一點, 然后連多幾個你就會發現超過數量后會報錯。
最終解決
其實還存在我沒提及的很多問題.. 例如 同一時間只能一方作為發送端的半雙工通訊。我們現在來解決, 我們需要將 recv() 和 send() 方法寫成異步非阻塞的就行了。
服務器
我們借助了多線程是我們的程序達到異步效果. ① 接收到一個連接后, 使用多線程交給 函數 handler_connect處理, 將 conn, addr 傳給該函數。② 循環接受數據. 此時是另一個線程在做不會影響主線程 accpet() 繼續接受連接
客戶端
邏輯和服務器差不多. 我們連接成功后, 開啟線程處理服務器響應信息, 循環發送信息. 直到主動退出, 此時服務器就可以同時處理多條連接了
總結
以上是生活随笔為你收集整理的python网络通信框架_Python运维-Socket网络编程 (1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring cloud config动
- 下一篇: python核心编程第二版pdf_Pyt