激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - python利用socketserver實現(xiàn)并發(fā)套接字功能

python利用socketserver實現(xiàn)并發(fā)套接字功能

2021-01-09 00:28成長的網(wǎng)工 Python

這篇文章主要為大家詳細介紹了python利用socketserver實現(xiàn)并發(fā)套接字功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實現(xiàn)利用pythonsocketserver這個強大的模塊實現(xiàn)套接字的并發(fā),具體內(nèi)容如下

目錄結(jié)構(gòu)如下:

python利用socketserver實現(xiàn)并發(fā)套接字功能

測試文件請放在server_file文件夾里面

server.py

?
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
#!/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è)置一個類,基礎(chǔ)BaseRequestHandler這個類
 def handle(self):     # 這個方法下添加通信功能(和上面創(chuàng)建類一樣,這是socketserver的固定模式)
  print(self.client_address)
  '''
  :functions: 使用socketserver的并發(fā)套接字,提供客戶端下載文件,并對文件進行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)小問題,不回復一個信息的話,發(fā)送給客戶端的包頭居然成了沒有封裝
     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進制
     file_header_bytes = file_header_dump.encode('gbk')
     # 封裝報頭
     file_header_struct = struct.pack('i',len(file_header_bytes))
     # 發(fā)送報頭
     self.request.send(file_header_struct)
     # 發(fā)送報文內(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ù)可以拓展一個進度或者網(wǎng)速顯示功能
   except Exception:
    self.request.close()
 
 
if __name__ == '__main__':
 server = ThreadingTCPServer(('127.0.0.1',8080),MYserver) # windows下只能開啟多線程
 server.serve_forever()

client.py

?
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/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'
 
 
# 顯示下載進度條功能,可以拓展為顯示下載速度(提示,因為每次傳輸4096個字節(jié),那么下載網(wǎng)速為KB/S,1KB個字節(jié)=1024B(字節(jié)),那么1s傳輸了多少個字節(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)容進行下載
  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')
  # 收到文件后,讀取文件進行加密,看是否與服務(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('文件驗證通過')
  else:
   print('文件損壞,刪除文件')
   os.remove(FILE_PATH+r'\%s' %data_file)
 
 
if __name__ == '__main__':
 run('127.0.0.1',8080)

自己可以設(shè)置一個多用戶登錄,然后測試,用戶下載同一個文件,分別存入每個用戶自己的家目錄下面,效果更好。

當然現(xiàn)在也能測試,開啟兩個客戶端同時下載文件。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.cnblogs.com/encp/archive/2018/01/26/8358432.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91美女视频在线观看 | 九九午夜 | 国产自在自线午夜精品视频在 | 欧美色视 | 欧美一级一区二区三区 | 美女一级视频 | 久久性生活免费视频 | 日日摸夜夜骑 | 草莓福利视频在线观看 | 国产精品欧美久久久久一区二区 | 久久久一区二区三区视频 | 久久影院免费观看 | av电影院在线观看 | 国产成人在线综合 | 国产99一区二区 | 视频一区二区三区在线 | 久久99在线| 午夜视频在线观 | 欧美日韩色 | 日韩大片在线永久观看视频网站免费 | 日韩字幕在线观看 | 午夜免费网 | 中国的免费的视频 | 免费日本一区二区 | 国产中出在线观看 | 91成人免费在线观看 | 国产一国产一级毛片视频在线 | 成人免费在线视频播放 | 成人一级免费视频 | 免费观看黄色影片 | 日本教室三级在线看 | 一级毛片特黄 | xxxx8| 国产色爱综合网 | 在线观看第一区 | 免费看一级视频 | 99爱视频 | 免费色片 | 99精品视频久久精品视频 | 亚洲精品成人在线视频 | 91成人在线免费观看 |