socket網路程式設計學習之tcp與udp
阿新 • • 發佈:2021-01-06
1.(TCP)面向連線的套接字
不管你採用的是哪種地址家族,都有兩種不同風格的套接字連線。第一種是面向連線的
這意味著在進行通訊之前必須先建立一個連線,例如,使用電話系統給一個朋友打電話。這
種類型的通訊也稱為虛擬電路或流套接字。48 第 1 部分 通用應用主題
面向連線的通訊提供序列化的、可靠的和不重複的資料交付,而沒有記錄邊界。這基本
上意味著每條訊息可以拆分成多個片段,並且每一條訊息片段都確保能夠到達目的地,然後
將它們按順序組合在一起,最後將完整訊息傳遞給正在等待的應用程式。
實現這種連線型別的主要協議是傳輸控制協議(更為人熟知的是它的縮寫 TCP)。為 了
SOCK_STREAM 基於流套接字的其中一種表示。因為這些套接字(AF_INET)的網路版本
使用因特網協議(IP)來搜尋網路中的主機,所以整個系統通常結合這兩種協議(TCP 和 IP)
來進行(當然,也可以使用 TCP 和本地[非網路的 AF_LOCAL/AF_UNIX]套接字,但是很明
顯此時並沒有使用 IP)。
2.(UDP)無連線的套接字
與虛擬電路形成鮮明對比的是資料報型別的套接字,它是一種無連線的套接字。這意味
著,在通訊開始之前並不需要建立連線。此時,在資料傳輸過程中並無法保證它的順序性、
並非首先分成多個片段,例如,使用面向連線的協議。
使用資料報的訊息傳輸可以比作郵政服務。信件和包裹或許並不能以傳送順序到達。
事實上,它們可能不會到達。為了將其新增到併發通訊中,在網路中甚至有可能存在重複
的訊息。
既然有這麼多副作用,為什麼還使用資料報呢(使用流套接字肯定有一些優勢)?由於面
向連線的套接字所提供的保證,因此它們的設定以及對虛擬電路連線的維護需要大量的開銷。
然而,資料報不需要這些開銷,即它的成本更加“低廉”。因此,它們通常能提供更好的效能,
並且可能適合一些型別的應用程式。
實現這種連線型別的主要協議是使用者資料報協議(更為人熟知的是其縮寫 UDP)。為 了
SOCK_DGRAM 名字來自於單詞“datagram”(資料報)。因為這些套接字也使用因特網協議
來尋找網路中的主機,所以這個系統也有一個更加普通的名字,即這兩種協議(UDP 和 IP)
的組合名字,或 UDP/IP。
TCP服務端客戶端例項
from socket import *
IP = '0.0.0.0'
PORT = 1314
BUFLEN = 512
ssk = socket(AF_INET, SOCK_STREAM)
ssk.bind((IP,PORT))
ssk.listen(5)
print("服務端啟動成功,等待客戶端連線。。。")
tsk, addr = ssk.accept()
print("接受客戶端連線:",addr)
while True:
#接受客戶端返回的位元組碼
recved = tsk.recv(BUFLEN)
if not recved:
break
message = recved.decode()#解碼成str
print (f'收到對方資訊:{message}')
# print('收到對方資訊:{message}')
tsk.send(f"服務端收到了資訊{message}".encode())#編碼字串
tsk.close()
ssk.close()
from socket import *
IP = '127.0.0.1'
SERVER_PORT = 1314
BUFLEN = 512
tsk = socket(AF_INET, SOCK_STREAM)
tsk.connect((IP, SERVER_PORT))
while True:
toSend = input('>>> ')
if toSend == 'byebye':
break
tsk.send(toSend.encode())
recved = tsk.recv(BUFLEN)
if not recved:
break
print(recved.decode())
tsk.close()
2.UDP服務端和客戶端
from socket import * #匯入socket
from time import ctime
print("---------------------------服務端udp------------------------------------")
#設定埠,地址
PORT = 520
IP = '0.0.0.0'
MAX = 1024
#建立socket物件
usk = socket(AF_INET,SOCK_DGRAM)
#繫結埠地址
usk.bind((IP,PORT))
print("服務端啟動成功")
#資訊傳輸
while True:
#接收資訊
data,addr = usk.recvfrom(MAX)
print("連線成功,等待對方傳送資訊")
usk.sendto(('[%s] %s' %(ctime(),data)).encode(),addr)
usk.close()
from socket import * #匯入socket
print("---------------------------客戶端udp------------------------------------")
#埠地址
PORT = 520
IP= '127.0.0.1'
MAX = 1024
#建立
psk = socket(AF_INET,SOCK_DGRAM)
# #連線
# psk.connect((IP,PORT))
while True:
data = input('>')
if not data:
break
psk.sendto(data.encode(),(IP,PORT))
data,(IP,PORT) = psk.recvfrom(MAX)
if not data:
break
print(data)
psk.close()