怎么在python中利用socketserver實(shí)現(xiàn)并發(fā)套接字功能?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

Python是一種編程語(yǔ)言,內(nèi)置了許多有效的工具,Python幾乎無(wú)所不能,該語(yǔ)言通俗易懂、容易入門(mén)、功能強(qiáng)大,在許多領(lǐng)域中都有廣泛的應(yīng)用,例如最熱門(mén)的大數(shù)據(jù)分析,人工智能,Web開(kāi)發(fā)等。
目錄結(jié)構(gòu)如下:

測(cè)試文件請(qǐng)放在server_file文件夾里面
server.py
#!/usr/bin/env python
# -*- coding: gbk -*-
# @Version : Python 3.5.2
# @Time : 2018/1/24 10:29
# @Author : Ncp
# @File : server.py
# @Software: PyCharm
import json
import time
import hashlib
import struct
import os
from socketserver import *
FILE_PATH = os.path.dirname(os.path.abspath(__file__))+'\\server_file'
class MYserver(BaseRequestHandler): # 設(shè)置一個(gè)類,基礎(chǔ)BaseRequestHandler這個(gè)類
def handle(self): # 這個(gè)方法下添加通信功能(和上面創(chuàng)建類一樣,這是socketserver的固定模式)
print(self.client_address)
'''
:functions: 使用socketserver的并發(fā)套接字,提供客戶端下載文件,并對(duì)文件進(jìn)行MD5加密
'''
while True:
try:
data = self.request.recv(1024)
data_recv = data.decode('gbk').split()
if not os.path.exists(FILE_PATH+r'\%s' %data_recv[1]):
self.request.send('file is not found'.encode('gbk'))
continue
else:
data = self.request.send('1'.encode('gbk')) # 這里發(fā)現(xiàn)小問(wèn)題,不回復(fù)一個(gè)信息的話,發(fā)送給客戶端的包頭居然成了沒(méi)有封裝
FILE_SIZE = os.path.getsize(FILE_PATH+r'\%s' %data_recv[1])
with open(FILE_PATH+r'\%s' %data_recv[1],'rb')as f:
hash_file = f.read()
m = hashlib.md5()
m.update(hash_file)
m_hex = m.hexdigest()
file_header = {'filename':data_recv[1],
'filesize':FILE_SIZE,
'md5':m_hex,
'time':time.strftime('%Y-%m-%d-%X',time.localtime())
}
# 包頭信息序列化
file_header_dump = json.dumps(file_header)
# 編譯成2進(jìn)制
file_header_bytes = file_header_dump.encode('gbk')
# 封裝報(bào)頭
file_header_struct = struct.pack('i',len(file_header_bytes))
# 發(fā)送報(bào)頭
self.request.send(file_header_struct)
# 發(fā)送報(bào)文內(nèi)容
self.request.send(file_header_bytes)
# 發(fā)送文件數(shù)據(jù)
send_size = 0
with open(FILE_PATH+r'\%s' %data_recv[1] , 'rb')as f:
for i in f:
self.request.send(i)
send_size += len(i) # 這里后續(xù)可以拓展一個(gè)進(jìn)度或者網(wǎng)速顯示功能
except Exception:
self.request.close()
if __name__ == '__main__':
server = ThreadingTCPServer(('127.0.0.1',8080),MYserver) # windows下只能開(kāi)啟多線程
server.serve_forever()client.py
#!/usr/bin/env python
# -*- coding: gbk -*-
# @Version : Python 3.5.2
# @Time : 2018/1/24 10:29
# @Author : Ncp
# @File : client.py
# @Software: PyCharm
from socket import *
import os,sys
import hashlib
import struct
import math
import json
FILE_PATH = os.path.dirname(os.path.abspath(__file__))+'\\client_file'
# 顯示下載進(jìn)度條功能,可以拓展為顯示下載速度(提示,因?yàn)槊看蝹鬏?096個(gè)字節(jié),那么下載網(wǎng)速為KB/S,1KB個(gè)字節(jié)=1024B(字節(jié)),那么1s傳輸了多少個(gè)字節(jié)呢?)
def progress(recvd, total):
fraction = '{:.0%}'.format(recvd / total)
sys.stdout.write('\r[%-30s] %s' % ('#' * int(math.floor(recvd * 30 / total)), fraction))
sys.stdout.flush()
if recvd == total:
sys.stdout.write('\n')
# 主函數(shù)
def run(ip,addr):
client = socket(AF_INET,SOCK_STREAM)
client.connect((ip,addr))
while True:
user_input = input('>>').strip()
cmd = user_input.split()
if len(cmd) != 2:
print('input format is error please use:get xx')
continue
if cmd[0] == 'get':
client.send(user_input.encode('gbk'))
data = client.recv(1024)
data_recv = data.decode('gbk')
if data_recv == 'file is not found':
print(data_recv)
continue
else:
print('commands is not found')
continue
# 收包頭,然后一系列處理
header = client.recv(4)
if not header:break
header_json_len = struct.unpack('i', header)[0]
header_json_bytes = client.recv(header_json_len)
header_josn = header_json_bytes.decode('gbk')
header_dic = json.loads(header_josn)
# 去除包頭內(nèi)容進(jìn)行下載
print(header_dic)
data_len = header_dic['filesize']
data_file = header_dic['filename']
data_md5 = header_dic['md5']
recv_size = 0
with open(FILE_PATH+r'\%s' %data_file,'wb')as fw:
while recv_size < data_len:
recv_data = client.recv(4096)
recv_size += len(recv_data)
fw.write(recv_data)
progress(recv_size,data_len)
print('Download completion, start validation')
# 收到文件后,讀取文件進(jìn)行加密,看是否與服務(wù)端下載的文件一致!
with open(FILE_PATH+r'\%s' %data_file,'rb')as fr:
data_total = fr.read()
m = hashlib.md5()
m.update(data_total)
m_hex = m.hexdigest()
if m_hex == data_md5:
print('文件驗(yàn)證通過(guò)')
else:
print('文件損壞,刪除文件')
os.remove(FILE_PATH+r'\%s' %data_file)
if __name__ == '__main__':
run('127.0.0.1',8080)關(guān)于怎么在python中利用socketserver實(shí)現(xiàn)并發(fā)套接字功能問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
分享題目:怎么在python中利用socketserver實(shí)現(xiàn)并發(fā)套接字功能-創(chuàng)新互聯(lián)
文章源于:http://www.chinadenli.net/article46/dcpgeg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、Google、微信公眾號(hào)、品牌網(wǎng)站建設(shè)、云服務(wù)器、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)