python網路編程之socket

來源:互聯網
上載者:User

標籤:客戶   request   效率   系統   tcp/ip協議   模組   recvfrom   演算法   用戶端串連   

  一、socket是什麼

  在TCP/IP五層協議中,工作在應用程式層的軟體程式要想把它的資料發送給網路另一端的電腦並讓那台電腦能把接收到的資料正常解析出來傳遞給對應的程式就需要按照互連網協議在資料的前面依次加上每一層的頭部資訊,如果這個過程讓程式員自己去完成就需要去瞭解每一層的協議的工作原理,這無疑是非常耗費時間的極大的降低開發效率,因此前人為了避免這種情況就在應用程式層和下面四層之間加入了socket層。socket層對下四層做了封裝並給開發人員提供了方便使用的介面,開發人員只需要遵循socket的規則去寫程式,socket就會協助我們把程式的資料加上應該有的下四層的頭部資訊,所以我們無需再為資料的封裝操心了。

 

 二、TCP協議的socket使用方法

  服務端基本格式:

  

import socketphone=socket.socket()  #建立socket對象,預設參數為family=AF_INET(基於網路的通訊端家族), type=SOCK_STREAM(使用TCP/IP協議),可以修改phone.bind((‘127.0.0.1‘,8081)) #服務端綁定IP和連接埠,方便用戶端串連phone.listen() #監聽是否有用戶端試圖串連while True:    conn,addr=phone.accept() #建立串連,傳回值是一個包含連線物件以及用戶端IP、連接埠元祖的大元祖    while True:        try:            data=conn.recv(1024)  #接收資料,bytes類型            conn.send(data.upper())  #發送資料,bytes類型        except Exception:            break    conn.close()  #關閉串連phone.close() #關閉socket

 

  用戶端基本格式:

  

import socketphone=socket.socket() #建立socket對象phone.connect((‘127.0.0.1‘,8081)) #串連服務端while True:    msg=input(‘>>:‘).strip()    if not msg:continue    phone.send(msg.encode(‘utf-8‘))  #發送資料,bytes類型    data=phone.recv(1024) #接收資料,bytes類型    print(data)

 

   三、UDP協議的socket使用方法

   服務端基本格式:

   

import socketip_port=(‘127.0.0.1‘,9000)BUFSIZE=1024udp_server_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)udp_server_client.bind(ip_port)while True:    msg,addr=udp_server_client.recvfrom(BUFSIZE) #接收的是發送端的訊息以及發送端地址的元祖    print(msg,addr)    udp_server_client.sendto(msg.upper(),addr)

 

  用戶端基本格式:

  

import socketip_port=(‘127.0.0.1‘,9000)BUFSIZE=1024udp_server_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)while True:    msg=input(‘>>: ‘).strip()    if not msg:continue    udp_server_client.sendto(msg.encode(‘utf-8‘),ip_port)    back_msg,addr=udp_server_client.recvfrom(BUFSIZE)    print(back_msg.decode(‘utf-8‘),addr)

 

 

  四、粘包

 1、什麼是粘包

  在一次發或者收的過程中多個資料包的資訊粘在了一起,造成資料混亂,要注意的是粘包只有TCP傳輸中會發生。

  2、成因

  發送端:TCP協議在傳輸資料的過程中會使用一種最佳化演算法,這種演算法為了減少網路延遲對傳輸資料的影響提高傳輸效率,在遇到短時間多個小資料包進入系統緩衝時會將這幾個資料包封裝在一起傳輸,這就造成了粘包。

  接收端:接收端接收一個資料包的資料時在沒有接收完的情況下又有一個新的資料包進入緩衝,這時就可能會產生粘包。

  3、解決方案

   1)在發送小資料包時中間間隔一個大於網路延遲的時間

    2)在發送真實資料前先告知接收端真實資料的長度

  4、利用struct模組自訂傳輸協議

   1、自訂前序,格式類似如下

    

head={‘cmd‘:‘put‘,‘filename‘:filepath,‘filesize‘:filesize}

   2、利用json模組將前序序列化並且轉碼為bytes類型方便傳輸

   3、計算轉碼後的前序長度

   4、利用struct模組將前序長度資訊封裝為固定長度的bytes類型資料,然後發送給接收端

   

head_pack=struct.pack(‘i‘,len(head_json.encode(‘utf-8‘))) #將數字轉換為4個位元組的bytes類型資料

 

   5、將轉碼後的前序發送給接收端

   6、發送真實資料

 

    五、socketserver

    服務端:

    

import socketserverimport structimport jsonimport osclass FtpServer(socketserver.BaseRequestHandler): #定義自己的socketserver類,繼承BaseRequestHandler    coding=‘utf-8‘    server_dir=‘file_upload‘    max_packet_size=1024    BASE_DIR=os.path.dirname(os.path.abspath(__file__))    def handle(self): #重寫handle方法,處理所有通訊過程        print(self.request)        while True:            data=self.request.recv(4)            data_len=struct.unpack(‘i‘,data)[0]            head_json=self.request.recv(data_len).decode(self.coding)            head_dic=json.loads(head_json)            # print(head_dic)            cmd=head_dic[‘cmd‘]            if hasattr(self,cmd):                func=getattr(self,cmd)                func(head_dic)    def put(self,args):        file_path = os.path.normpath(os.path.join(            self.BASE_DIR,            self.server_dir,            args[‘filename‘]        ))        filesize = args[‘filesize‘]        recv_size = 0        print(‘----->‘, file_path)        with open(file_path, ‘wb‘) as f:            while recv_size < filesize:                recv_data = self.request.recv(self.max_packet_size)                f.write(recv_data)                recv_size += len(recv_data)                print(‘recvsize:%s filesize:%s‘ % (recv_size, filesize))ftpserver=socketserver.ThreadingTCPServer((‘127.0.0.1‘,8080),FtpServer)#執行個體化一個server對象並將服務端的IP和連接埠以及自己定義的socketserver類的類名傳入ftpserver.serve_forever()#啟動socketserver並永久運行

 

  用戶端:

  只需要使用socket即可

python網路編程之socket

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.