Python socket 套接字實現通信


首先:我們介紹一下socket什么是socket:
1. socket 在操作系統中它是處於應用層與傳輸層的抽象層,它是一組操作起來非常簡單的接口(接收數據的),此接口接受數據之后交個操作系統
那么為什么?直接給操作系統不是更方便嗎?那么你就想錯了

因為操作系統的接口遠比我們想象的要丑陋復雜,使用操作系統交換數據,非誠繁瑣,,開發者們只能想辦法讓一個中間人和他們打交道,來簡單的實現數據交換,那么就是socket套接字.它的作用就是:與操作系統之間數據交換將這些繁瑣的操作,進行高度化封裝,和簡化,
2.我們能夠用它實現簡單的通信
在Python中有一個簡單的內置socket 模塊我們可以用它實現簡單的基於TCP協議的通信

    #基於切換連接的循環通信
    import socket #首先我們在文件中導入socket 模塊
    phone = socket.socket() #實例化一個對象
    phone.bind(('127.0.01',8765))#bind是存放ip地址的(這里存放的是本地的IP地址)
    phone.listen(5)#可以設置連接的個數,
    while 1:#循環等待連接
        conn,adds = phone.accept()
        while 1:#要循環聊天我們要重復接收發送
            try: #異常處理
            	receives_commands = conn.recv(1024) #接收命令請求,最多接收1024字節當然你也可以調整
                receivse_commands = receives_commands.decode('utf-8')#網絡傳輸是以字節的形勢的所以我們要進行解碼
                print(f'來自客戶端的消息{receives_commands}')  #打印消息
                if receives_commands.upper(0 == 'Q':break  #正常結束
                dispatch_orders = inport('請輸入:').strip().encode('utf-8')
    			conn.send(dispatch_orders)
           except ConnectionResetError:#客戶端異常結束
           		print('客戶端終端')
                break
       conn.close() #關閉連接
    phone.close#關閉服務端
    #客戶端
    import socket
    phone = socket.socket()
    phone.connect(('127.0.01',8765))        #連接服務端地址            
 while 1:                  
        dispatch_orders = inport('請輸入:').strip().encode('utf-8')#發送請求
        if not dispatch_orders:print('不能為空')#不能為空
        phone.send(dispatch_orders)      #發送                        
        if dispatch_orders.upper() ==b'Q':#正常退出
            break
        receives_commands = phone.recv(1024)#接收服務端的回執
        receives_commands = receives_commands.decode('utf-8')#解碼
        print(f'來自客戶端的消息{receives_commands}')   #打印                                
    phone.close()#關閉客戶端
                                           

那么我們就通過socket實現了一個簡單的通信鏈接循環
其中我們需要注意的是:
1.阻塞 accept 和recv 當服務器和客戶端都屬於同種類阻塞時,那么誰都是同步接受或同步發送的狀態那么是處於靜止的,這樣是不合理的(就是bug)
2.當我們設計時我們需要知道發送不能為空,不然服務端是接收不到消息的所以我們設置一個判斷
有時我們會發現當我們接受的超過1024字節會發生什么?
那么下面我們就來將回答下這個問題:
下面我們引入一個操作系統的模塊
Python中 subprocess 模塊就是用來和cmd 命令行進行交流的模塊

 obj = subprocess.Popen('dir',#實例化對象括號內第一個參數就是我們的cmd命令行的命令,這里我們寫的是dir顯示文件夾中內容
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,

                                   )

            print(obj.stdout.read().decode('gbk'))  # 正確命令
            print(obj.stderr.read().decode('gbk'))  # 錯誤命令

那么我們在這個基礎上建立一個服務端響應客戶端命令的機制

import socket
import subprocess
phone = socket.socket()
phone.bind(('127.0.01',8695))
phone.listen(5)
while 1:
    conn,adds = phone.accept()
    while 1:
        try:
            receives_commands = conn.recv(1024)
            if receiver_commands ==b'Q':break 
            #obj = subprocess.Popen(Receiving_instructiors,
                                  # shell= True,
                          #stdout = subprocess.PIPE,
                          #stderr = subprocess.PIPE

                                   )
    	obj = subprocess.Popen(receives_commands.decode('utf-8')#動態的傳入命令
                          shell = True
                          stdout = subprocess.PIPE
                          stderr = subprocess.PIPE 
                          )
  # print(obj.stdout.read().decode('gbk'))  # 正確命令
  # print(obj.stderr.read().decode('gbk'))  # 錯誤命令
    	ret = obj.stodut.read()+obj.stderr.read()#將產生的內容進行拼接
    	conn.send(ret)
    except ConnectionResetError:
       		print('客戶端終端')
            break    
    conn.close()
phone.close()

import socket

phone = socket.socket()

phone.connect(('127.0.01',8695))
while 1:
    dispatch_orders = inport('請輸入命令:').strip().encode('utf-8')
    if not dispatch_orders:print('輸入不能為空')
    phone.send(dispatch_orders)
    if dispatch_orders.upper() ==b'Q':break
    receives_commands = phone.recv(1024)
    receives_commands = receives_commands.decode('utf-8')
    print(f'來自客戶端的消息{receives_commands}')
phone.close()     

那么我們就會發現一個問題,當我們輸入的help命令的時候超過了1024字節那么怎么辦
還發現一個問題那就是當我們輸入的下個命令時,還是出來help命令的未傳輸完成的那部分那么就是這就是粘包了
那么是什么造成的呢?
怎樣解決呢?
下個博客講解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM