【python网络编程】创建TCP/UDP服务器进行客户端/服务器间通信
- 客戶端/服務器網絡編程介紹
- 套接字:通信端點
- 實例:客戶端發送數據,接收服務器返回的時間戳
- 用Python 編寫FTP 客戶端程序
客戶端/服務器網絡編程介紹
軟件服務器也運行在一塊硬件之上,但是沒有像硬件服務器那樣的專用外圍設備(如打印機、磁盤驅動器等)。軟件服務器提供的主要服務包括程序執行、數據傳輸檢索、聚合、更新,或其他類型的編程或數據操作。
現在一個更常見的軟件服務器就是Web 服務器。如果個人或公司想要運行自己的Web 服務器,那么必須擁有一臺或多臺計算機,在上面安裝希望提供給用戶的Web 頁面和Web 應用程序,然后啟動Web 服務器。一個這樣的服務器的工作就是接受客戶端請求,并向(Web)客戶端(即用戶計算機上的瀏覽器)回送Web 頁面,然后等待下一個客戶端的請求。這些服務器一旦開啟,都將可能永遠運行。雖然它們并不能實現這一目標,但是它們會盡可能長時間地運行,除非受到一些外力驅使才會停止,如顯式地關閉,或災難性地關閉(由于硬件故障)。
數據庫服務器是另一種類型的軟件服務器。它們接受客戶端的存儲或檢索請求,響應請求,然后等待更多的事務。與Web 服務器類似,它們也是永遠運行的。
在服務器響應客戶端請求之前,必須進行一些初步的設置流程來為之后的工作做準備。
首先會創建一個通信端點,它能夠使服務器監聽請求。可以把服務器比作公司前臺,或者應答公司主線呼叫的總機接線員。一旦電話號碼和設備安裝成功且接線員到達時,服務就可以
開始了。
套接字:通信端點
套接字是計算機網絡數據結構,它體現了上節中所描述的“通信端點”的概念。在任何類型的通信開始之前,網絡應用程序必須創建套接字。可以將它們比作電話插孔,沒有它將無法進行通信。
套接字最初是為同一主機上的應用程序所創建,使得主機上運行的一個程序(又名一個進程)與另一個運行的程序進行通信。這就是所謂的進程間通信(Inter Process Communication,IPC)。有兩種類型的套接字:基于文件的和面向網絡的。
1.面向連接的套接字
不管你采用的是哪種地址家族,都有兩種不同風格的套接字連接。第一種是面向連接的,這意味著在進行通信之前必須先建立一個連接,例如,使用電話系統給一個朋友打電話。這
種類型的通信也稱為虛擬電路或流套接字。
面向連接的通信提供序列化的、可靠的和不重復的數據交付,而沒有記錄邊界。這基本上意味著每條消息可以拆分成多個片段,并且每一條消息片段都確保能夠到達目的地,然后將它們按順序組合在一起,最后將完整消息傳遞給正在等待的應用程序。
實現這種連接類型的主要協議是傳輸控制協議(更為人熟知的是它的縮寫TCP)。為了創建TCP 套接字,必須使用SOCK_STREAM 作為套接字類型。TCP 套接字的名字
SOCK_STREAM 基于流套接字的其中一種表示。因為這些套接字(AF_INET)的網絡版本使用因特網協議(IP)來搜尋網絡中的主機,所以整個系統通常結合這兩種協議(TCP 和IP)來進行(當然,也可以使用TCP 和本地[非網絡的AF_LOCAL/AF_UNIX]套接字,但是很明顯此時并沒有使用IP)。
2.無連接的套接字
與虛擬電路形成鮮明對比的是數據報類型的套接字,它是一種無連接的套接字。這意味著,在通信開始之前并不需要建立連接。此時,在數據傳輸過程中并無法保證它的順序性、可靠性或重復性。然而,數據報確實保存了記錄邊界,這就意味著消息是以整體發送的,而并非首先分成多個片段,例如,使用面向連接的協議。
使用數據報的消息傳輸可以比作郵政服務。信件和包裹或許并不能以發送順序到達。
事實上,它們可能不會到達。為了將其添加到并發通信中,在網絡中甚至有可能存在重復的消息。
既然有這么多副作用,為什么還使用數據報呢(使用流套接字肯定有一些優勢)?由于面向連接的套接字所提供的保證,因此它們的設置以及對虛擬電路連接的維護需要大量的開銷。
然而,數據報不需要這些開銷,即它的成本更加“低廉”。因此,它們通常能提供更好的性能,并且可能適合一些類型的應用程序。
實現這種連接類型的主要協議是用戶數據報協議(更為人熟知的是其縮寫UDP)。為了創建UDP 套接字,必須使用SOCK_DGRAM 作為套接字類型。
為了創建TCP/IP 套接字,可以用下面的方式調用socket.socket()。
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
同樣,為了創建UDP/IP 套接字,需要執行以下語句。
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
服務器套接字方法
s.bind() 將地址(主機名、端口號對)綁定到套接字上
s.listen() 設置并啟動TCP 監聽器
s.accept() 被動接受TCP 客戶端連接,一直等待直到連接到達(阻塞)
客戶端套接字方法
s.connect() 主動發起TCP 服務器連接
s.connect_ex() connect()的擴展版本,此時會以錯誤碼的形式返回問題,而不是拋出一個異常
普通的套接字方法
| s.recv_into() | ① 接收TCP 消息到指定的緩沖區 |
| s.send() | 發送TCP 消息 |
| s.sendall() | 完整地發送TCP 消息 |
| s.recvfrom() | 接收UDP 消息 |
| s.recvfrom_into() | 接收UDP 消息到指定的緩沖區 |
| s.sendto() | 發送UDP 消息 |
| s.getpeername() | 連接到套接字(TCP)的遠程地址 |
| s.getsockname() | 當前套接字的地址 |
| s.getsockopt() | 返回給定套接字選項的值 |
| s.setsockopt() | 設置給定套接字選項的值 |
| – | – |
| s.close() | 關閉套接字 |
| s.detach() | 在未關閉文件描述符的情況下關閉套接字,返回文件描述符 |
實例:客戶端發送數據,接收服務器返回的時間戳
服務端:
from socket import * from time import ctime #創建一個TCP 服務器,它接受來自客戶端的消息,并返回加了時間戳前綴的相同消息。 host='' port=21567 bufsiz=1024 addr=(host,port) tcpServer=socket(AF_INET,SOCK_STREAM) tcpServer.bind(addr) tcpServer.listen(5) while True:print('wait for connection..')tcpCliServer,addr= tcpServer.accept()print('..connect from',addr)while True:data = tcpCliServer.recv(bufsiz).decode()if not data:break#tcpCliServer.send('[%s]%s' % (bytes(ctime(),'utf-8'),str.encode(data)))tcpCliServer.send(bytes(ctime(), 'utf-8'))tcpCliServer.close()tcpServer.close()客戶端:
from socket import * host='localhost' port=21567 bufsize=1024 addr=(host,port) tcpClient=socket(AF_INET,SOCK_STREAM) tcpClient.connect(addr) while True:data=input('>')if not data:breaktcpClient.send(str.encode(data))data=tcpClient.recv(bufsize)if not data:breakprint(data) tcpClient.close()結果:
主要注意點是在編碼和解碼上。
若要創建UDP服務器只要將參數改為UdpServer=socket(AF_INET,SOCK_DGRAM)即可
用Python 編寫FTP 客戶端程序
文件傳輸協議(File Transfer Protocol,FTP)于1985 年10 月發布。FTP 主要用于匿名下載公共文件,也可以用于在兩臺計算機之間傳輸文件,特別是在使用Windows 進行工作,而文件存儲系統使用UNIX 的情況下。早在Web 流行之前,FTP 就是在因特網上進行文件傳輸以及下載軟件和源代碼的主要手段之一。
流程:
1.客戶端連接遠程主機上的FTP 服務器。
2.客戶端輸入用戶名和密碼(或“anonymous”和電子郵件地址)。
3.客戶端進行各種文件傳輸和信息查詢操作。
4.客戶端從遠程FTP 服務器退出,結束傳輸。
在底層,FTP 只使用TCP,而不使用UDP。另外,可以將FTP 看作客戶端/服務器編程中的特殊情況。因為這里的客戶端和服務器都使用兩個套接字來通信:一個是控制和命令端口(21 號端口),另一個是數據端口(有時是20 號端口)
用Python 編寫FTP 客戶端程序:
1.連接到服務器。
2.登錄。
3.發出服務請求(希望能得到響應)。
4.退出
from ftplib import FTP
f = FTP(‘some.ftp.server’)
f.login(‘anonymous’, ‘your@email.address’)
:
f. quit()
在一般的FTP 事務中,要使用到的指令有login()、cwd()、dir()、pwd()、stor*()、retr*()和quit()。
FTP 不僅可以用于下載應用程序,還可以用于在不同系統之間傳輸文件。比如,如果需要傳輸文件。在跨網絡的時候,顯然可以使用scp 或rsync 命令,或者把文件放到一個能從外部訪問的服務器上。不過,在一個安全網絡的內部機器之間移動大量的日志或數據庫文件時,這種方法的開銷就太大了,因為需要考慮安全性、加密、壓縮、解壓縮等因素。
如果只是想寫一個FTP 程序來在下班后自動移動文件,那么使用Python 是一個非常好的主意。
總結
以上是生活随笔為你收集整理的【python网络编程】创建TCP/UDP服务器进行客户端/服务器间通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【算法学习笔记】哈夫曼树的构建和哈夫曼编
- 下一篇: 【实例记录】在ubuntu上运行pyth