1. 程式人生 > >python3 下的Socket程式設計(TCP&UDP )

python3 下的Socket程式設計(TCP&UDP )

網路程式設計中最重要的兩個協議:TCP協議和UDP協議

TCP協議是網際網路中使用最廣泛的傳輸協議,這得益於其穩定,可靠的優勢。TCP協議是面向連線的傳輸協議,通訊雙方(通常是兩個主機上面的兩個程式)需要先建立連線,才能傳輸資料。資料在傳輸過程中會被分成多個小的資料包,這些資料包都會被新增上序號,全部達到接收端的小資料包會根據這些序號重新拼湊起來。TCP傳輸的資料包加入了檢驗碼,可以檢測在傳輸過程中資料包是否被更改過,對於更改過或者損失了資料的資料包,接收端會要求傳送端重新發送。接收端在收到傳送端傳送的資料包之後,會回送一個訊息到傳送端,告訴傳送端已經安全接收到資料包了,如果傳送端沒有收到這個回送訊息,則會經過一段時間再次傳送該資料包。因此在這種協議下面,資料的傳輸是十分穩定可靠的。

UDP協議是一類無連線的傳輸協議。傳送端只管將資料傳送出去,接收端收到資料後也不會發送回送訊息給傳送端,因此傳送端並不知道接收端有沒有收到完整的資料。TCP需要的時間和系統開銷都比UDP大,UDP在傳輸一些小資料時有一定的優勢,通常來說UDP一次傳輸的資料大小不能超過64kb,一般來說最佳的資料大小是<1kb。

python3可以使用socket模組簡單的實現TCP與UDP傳輸協議,下面看伺服器和客戶端程式碼

TCP傳輸的python3程式碼:

 
  
  #伺服器端程式碼++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#/usr/bin/env python import  socket import  time host = '' port = 51423 bufsize = 1024 addr = ( host , port ) #host設定為空,表示可以與任何ip的socket在埠51423通訊 #設定socket,AF_INET表示是IPV4標準,SOCK_STREAM是TCP傳輸協議 tcpSerSock
= socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) tcpSerSock . bind ( addr ) tcpSerSock . listen ( 1 ) quit = False shutdown = False while  True : print ( 'waiting for connection...' ) tcpCliSock , addr = tcpSerSock . accept () #不斷監聽獲取新的客戶端連線 print ( '...connected from:' , addr ) while  True : #與客戶端建立連線之後,獲取客戶端傳來的資料 data = tcpCliSock . recv ( bufsize ) data = data . decode ( 'utf-8' ) if  not  data : break ss = '[ %s %s ' % ( time . ctime (), data ) tcpCliSock . sendall ( ss . encode ( 'utf-8' )) print ( ss ) if  data == 'bye' : quit = True break elif  data == 'shutdown' : shutdown = True break print ( 'Bye-bye:[ %s : %d ]' % ( addr [ 0 ], addr [ 1 ])) tcpCliSock . close () if  shutdown : break tcpSerSock . close () print ( 'Server has been closed' ) #客戶端程式碼+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ import  socket host = '192.168.1.147' port = 51423 bufsize = 1024 addr = ( host , port ) tcpCliSock = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) tcpCliSock . connect ( addr ) while  True : data = input ( '>' ) if  not  data : continue print ( 'input data:[ %s ]'  % data ) tcpCliSock . sendall ( data . encode ( 'utf-8' )) rdata = tcpCliSock . recv ( bufsize ) if  not  rdata : break print ( rdata . decode ( 'utf-8' )) if  data == 'bye'  or  data == 'shutdown' : break 首先啟動伺服器程式碼,然後在啟動客戶端程式碼,這樣伺服器與客戶端就建立了連線。在客戶端控制檯輸入的資料會在伺服器控制檯顯示出來。客戶端輸入'bye'字元時,伺服器會關閉客戶端的socket連線,客戶端輸入'shutdown'時,伺服器關閉客戶端和伺服器端的socket連線。

測試程式碼時最好能用兩臺電腦測試。也可以像博主一樣在一臺電腦上面裝一個虛擬機器作業系統,使用橋接模式,也可以模擬客戶端和伺服器端完成端到端測試。

UDP傳輸的python程式碼:

#伺服器端++++++++++++++++++++++++++++++++++++++++++++++++

import socket

BUFF_SIZE = 1024
server_addr = ('127.0.0.1', 55555)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)            # SOCK_DGRAM是UDP傳輸協議
s.bind(server_addr)
print('bind ok!')

while True:
    data, addr = s.recvfrom(BUFF_SIZE)
    print(data)
    if data is 'bye':
        print('client has exit')
        break
    print('received:', data, " from", addr)
s.close()


#客戶端+++++++++++++++++++++++++++++++++++++++++++++++++++++

import socket

server_addr = ('127.0.0.1', 55555)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
    msg = input('>')
    print(msg)
    s.sendto(msg.encode('utf-8'), server_addr)
    if msg is 'bye':
        break
s.close()

UDP由於是無連線的傳輸協議,因此這裡建立的socket物件不需要呼叫connnect()方法建立連線,可以直接使用sendto()和recvfrom()來發送和接收資料。UDP協議並不可靠,傳送端不知道接受端有沒有收到資料,傳送端就只在傳送的時候傳送一次資料,如果網路擁塞很有可能造成接收端沒有正常接收到資料。TCP連線會多次重發資料,直到接收到來自接收方的回送訊息為止。