Python網路程式設計基礎
阿新 • • 發佈:2019-01-25
文章簡介:
- TCP和UDP套接字通訊的特點
- TCP客戶端與伺服器
- UDP客戶端與伺服器
TCP和UDP套接字通訊特點
TCP套接字是面向連線的套接字,這意味著在開始通訊之前必須先建立一個連線。
UDP套接字是無連線的套接字,也稱為資料報,即在開始通訊之前並不需要建立連線。
面向連線的套接字提供一種序列化的、可靠的和不重複的資料交付,而沒有記錄邊界。這基本上意味著每條訊息可以拆分成多個片段,並且每一條訊息都能夠到達目的地,然後它們將按照順序組合在一起,最後將完整的訊息傳遞給正在等待的應用程式。
反之,無連線的套接字在資料傳輸過程中無法保證它的順序性、可靠性和不重複性,並且在資料傳輸過程中還有可能出現數據丟失的情況。但是,資料報確實儲存了邊界,這就意味著訊息是以整體傳送的,並不會分成多個片段,同時,相對於面向連線到套接字,無連線套接字的開銷更低,成本也更加低廉,通常能夠提供更好的效能。
TCP客戶端與伺服器
- TCP客戶端
首先,來看TCP伺服器的程式碼
#coding:utf-8
from socket import *
HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024 #設定資料緩衝區大小
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM) #建立套接字
tcpSerSock.bind(ADDR) #繫結套接字地址
tcpSerSock.listen(5) #開啟監聽
while True:
print('waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept() #接收客戶端的連線
print('...connected from:', addr)
while True:
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
print(data)
data_1 = input('> ')
tcpCliSock.send(data_1.encode('utf-8'))
tcpCliSock.close()
HOST = 'localhost'
PORT = 21567
此處HOST和PORT的設定都是伺服器的IP地址。
tcpSerSock.listen(5) #開啟監聽
在伺服器開啟監聽程式碼中,引數“5”的意義是允許排隊等待的連線數目。即伺服器允許的客戶端的最大連線請求數目。
tcpCliSock, addr = tcpSerSock.accept() #接收客戶端的連線
呼叫函式accept(),伺服器會佔用一個埠,等待客戶端的連線。一旦伺服器接受一個客戶端的連線,accept()函式就會返回一個獨立的客戶端套接字(如:tcpCliSock)和一個地址(addr)。這個獨立的伺服器套接字(tcpCliSock)負責與客戶端通訊,這樣就可以空出原始的客戶端套接字(tcpSerSock),伺服器就可以繼續接收其他客戶端的連線請求。
接收得到的地址(addr)是客戶端的IP地址。
- TCP伺服器
#coding:utf-8
from socket import *
HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
while True:
data = input('>')
if not data:
break
tcpCliSock.send(data.encode('utf-8'))
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
print(data)
tcpCliSock.close()
HOST = 'localhost'
此處變數HOST需注意,因為客戶端與伺服器在同一臺計算機上,所以此處的HOST是本地主機名。如果客戶端和伺服器不在同一主機上,那麼HOST引數必須設定成相應的伺服器所在的主機名。
如果使用WINDOWS系統,那麼可直接在CMD環境下執行客戶端和伺服器。
在CMD下切換目錄至客戶端和伺服器檔案所在目錄,然後可按照如下命令執行伺服器和客戶端(先執行伺服器,然後執行客戶端)
伺服器執行效果
客戶端執行效果
UDP客戶端與伺服器
- UDP伺服器
UDP伺服器不是面向連線的,因此不需要TCP伺服器那麼多設定。
我們先來看UDP伺服器的虛擬碼
ss = socket()#建立伺服器套接字
ss.bind()#繫結伺服器套接字
ifn_loop:
cs = ss.recvfrom()/ss.sendto()#伺服器無限迴圈,接收發送資料
ss.close()#關閉伺服器套接字
UDP伺服器的完整程式碼:
from socket import *
HOST = 'localhost'
PORT = 21567
BUFISE = 1024
ADDR = (HOST, PORT)
udpSerSock = socket(AF_INET, SOCK_DGRAM)#建立套接字
udpSerSock.bind(ADDR)
while True:
print('waiting for message...')
data, addr = udpSerSock.recvfrom(BUFISE)
print(data)
data_1 = input('> ')
udpSerSock.sendto(data_1.encode('utf-8'), addr)
print('...received from and returned to:', addr)
同樣的,recvfrom函式返回連線伺服器的客戶端的地址和接收到的資料。
- UDP客戶端
from socket import *
HOST = 'localhost'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)
udpCliSock = socket(AF_INET, SOCK_DGRAM)
while True:
data = input('> ')
if not data:
break
udpCliSock.sendto(data.encode('utf-8'), ADDR)
data, ADDR = udpCliSock.recvfrom(BUFSIZE)
if not data:
break
print(data)
udpCliSock.close()