利用python3來實現tcp協議,和udp類似。udp應用于及時通信,而tcp協議用來傳送文件、命令等操作,因為這些數據不允許丟失,否則會造成文件錯誤或命令混亂。下面代碼就是模擬客戶端通過命令行操作服務器。客戶端輸入命令,服務器執行并且返回結果。
tcp(transmission control protocol 傳輸控制協議):是一種面向連接的、可靠的、基于字節流的傳輸層通信協議,由ietf的rfc 793定義。
使用tcp編寫一個簡易的文件下載器要求:需編寫文件下載器服務端和文件下載器客戶端
服務器端代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
import socket import os import threading # 處理客戶端請求下載文件的操作(從主線程提出來的代碼) def deal_client_request(ip_port, service_client_socket): # 連接成功后,輸出“客戶端連接成功”和客戶端的ip和端口 print ( "客戶端連接成功" , ip_port) # 接收客戶端的請求信息 file_name = service_client_socket.recv( 1024 ) # 解碼 file_name_data = file_name.decode( "utf-8" ) # 判斷文件是否存在 if os.path.exists(file_name_data): #輸出文件字節數 fsize = os.path.getsize(file_name_data) #轉化為兆單位 fmb = fsize / float ( 1024 * 1024 ) #要傳輸的文件信息 senddata = "文件名:%s 文件大小:%.2fmb" % (file_name_data,fmb) #發送和打印文件信息 service_client_socket.send(senddata.encode( "utf-8" )) print ( "請求文件名:%s 文件大小:%.2f mb" % (file_name_data,fmb)) #接受客戶是否需要下載 options = service_client_socket.recv( 1024 ) if options.decode( "utf-8" ) = = "y" : # 打開文件 with open (file_name_data, "rb" ) as f: # 計算總數據包數目 nums = fsize / 1024 # 當前傳輸的數據包數目 cnum = 0 while true: file_data = f.read( 1024 ) cnum = cnum + 1 jindu = cnum / nums * 100 print ( "當前已下載:%.2f%%" % jindu,end = "\r" ) if file_data: # 只要讀取到數據,就向客戶端進行發送 service_client_socket.send(file_data) # 數據讀完,退出循環 else : print ( "請求的文件數據發送完成" ) break else : print ( "下載取消!" ) else : print ( "下載的文件不存在!" ) # 關閉服務當前客戶端的套接字 service_client_socket.close() if __name__ = = '__main__' : # 把工作目錄切換到data目錄下 os.chdir( "./data" ) # 創建套接字 tcp_server_socket = socket.socket(socket.af_inet, socket.sock_stream) # 綁定端口號 tcp_server_socket.bind(("", 3356 )) # 設置監聽,將主動套接字變為被動套接字 tcp_server_socket.listen( 128 ) # 循環調用accept,可以支持多個客戶端同時連接,和多個客戶端同時下載文件 while true: service_client_socket, ip_port = tcp_server_socket.accept() # 連接成功后打印套接字號 #print(id(service_client_socket)) # 創建子線程 sub_thread = threading.thread(target = deal_client_request, args = (ip_port, service_client_socket)) # 啟動子線程 sub_thread.start() |
客戶端代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# 多任務文件下載器客戶端 import socket if __name__ = = '__main__' : # 創建套接字 tcp_client_socket = socket.socket(socket.af_inet, socket.sock_stream) # 和服務端連接 server_ip = input ( "輸入服務器ip:" ) tcp_client_socket.connect((server_ip, 3356 )) # 發送下載文件的請求 file_name = input ( "請輸入要下載的文件名:" ) # 編碼 file_name_data = file_name.encode( "utf-8" ) # 發送文件下載請求數據 tcp_client_socket.send(file_name_data) # 接收要下載的文件信息 file_info = tcp_client_socket.recv( 1024 ) # 文件信息解碼 info_decode = file_info.decode( "utf-8" ) print (info_decode) #獲取文件大小 fileszie = float (info_decode.split( ':' )[ 2 ].split( 'mb' )[ 0 ]) fileszie2 = fileszie * 1024 # 是否下載?輸入y 確認 輸入q 取消 opts = input ( "是否下載?(y 確認 q 取消)" ) if opts = = 'q' : print ( "下載取消!程序退出" ) else : print ( "正在下載 》》》" ) #向服務器確認正在下載 tcp_client_socket.send(b 'y' ) # 把數據寫入到文件里 with open ( "./" + file_name, "wb" ) as file : #目前接收到的數據包數目 cnum = 0 while true: # 循環接收文件數據 file_data = tcp_client_socket.recv( 1024 ) # 接收到數據 if file_data: # 寫入數據 file .write(file_data) cnum = cnum + 1 jindu = cnum / fileszie2 * 100 print ( "當前已下載:%.2f%%" % jindu,end = "\r" ) # 接收完成 else : print ( "下載結束!" ) break # 關閉套接字 tcp_client_socket.close() |
運行窗口如下:
1)服務器端
2)客戶端
注意:客戶端和服務器端不要運行在idle中,直接使用終端運行。
總結
以上所述是小編給大家介紹的python3使用tcp編寫一個簡易的文件下載器功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!原文鏈接:https://www.linuxidc.com/Linux/2019-05/158530.htm