网络基础补充,断点续传,以及如何添加进度条
2018-09-10 01:06:21来源:博客园 阅读 ()
一丶网络基础补充
端口:
端口是为了将同一个电脑上的不同程序进行隔离,
每一个程序都有一个自己的端口,程序通过自己的那个端口来进行一些操作如:
MySQL是一个软件,软件帮助我们在硬盘上进行文件操作。默认端口:3306
Redis是一个软件,软件帮助我们在内存里进行数据操作。默认端口:6379
网站默认端口:80 ,访问时:http://www.luffycity.com:80
网站默认端口:443 ,访问时:https://www.luffycity.com:443
OSI七层模型
人们按照分工不同把互联网协议从逻辑上划分了层级:
第一层: 物理层
主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的模数转换与数模转换)。这一层的数据叫做比特。
第二层: 数据链路层
主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装。常把这一层的数据叫做帧。在这一层工作的设备是交换机,数据通过交换机来传输。
第三层: 网络层
主要将从下层接收到的数据进行IP地址(例192.168.0.1)的封装与解封装。在这一层工作的设备是路由器,常把这一层的数据叫做数据包。
第四层: 传输层
定义了一些传输数据的协议和端口号(WWW端口80等),如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据),UDP(用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ聊天数据就是通过这种方式传输的)。 主要是将从下层接收的数据进行分段进行传输,到达目的地址后在进行重组。常常把这一层数据叫做段。
第五层: 会话层
通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)
第六层: 表示层
主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等(也就是把计算机能够识别的东西转换成人能够能识别的东西(如图片、声音等))
第七层: 应用层
主要是一些终端的应用,比如说FTP(各种文件下载),WEB(IE浏览),QQ之类的(你就把它理解成我们在电脑屏幕上可以看到的东西.就 是终端应用)。
TCP三次握手与四次挥手:
TCP建立连接为什么是三次握手,而不是两次或四次?
TCP,名为传输控制协议,是一种可靠的传输层协议,IP协议号为6。
顺便说一句,原则上任何数据传输都无法确保绝对可靠,三次握手只是确保可靠的基本需要。
举个日常例子,打电话时我们对话如下:
对应的客户端与服务端如下:
四次挥手:
先由客户端向服务器端发送一个FIN,请求关闭数据传输。
当服务器接收到客户端的FIN时,向客户端发送一个ACK,其中ack的值等于FIN+SEQ
然后服务器向客户端发送一个FIN,告诉客户端应用程序关闭。
当客户端收到服务器端的FIN是,回复一个ACK给服务器端。其中ack的值等于FIN+SEQ
我们为什么要四次挥手呢?
确保数据能够完整传输
当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了.
但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,
再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的
二丶断点续传
服务端:
import socketserver import hashlib import json import struct import os class Myserver(socketserver.BaseRequestHandler): def handle(self): while 1: print("等待用户输入....") num = self.request.recv(8096).decode("utf8") num = int(num) if num == 1: #接收文件 md5 = hashlib.md5() file_info_json = self.request.recv(8096) file_info = json.loads(file_info_json) filename = file_info.get("filename") file_size = file_info.get("file_size") if os.path.isfile("put/" + "%s副本" % filename): # 如果是存在的文件,返回True.否则返回False) filename_size = os.path.getsize("put/" + "%s副本" % filename) # 返回path的大小 else: filename_size = 0 filename_size_struct = struct.pack("i", filename_size) self.request.send(filename_size_struct) # 发送文件大小 # 循环接收文件 with open("put/" + "%s副本" % filename, "ab") as f: while filename_size < file_size: data = self.request.recv(8096) filename_size += len(data) f.write(data) # MD5摘要 md5.update(data) # 写入要加密的的东西 # print("文件总大小:%s,已成功接收%s" % (filesize, recv_data_length)) self.request.send(b"OK") md5_val = md5.hexdigest() # 解密 client_md5 = self.request.recv(8096).decode('utf8') if md5_val == client_md5: self.request.send(b"203") print("接收成功!") os.rename("put/" + "%s副本" % filename, "put/" + filename) break # else: # self.request.send(b"204") # print("接收失败!") elif num == 2: #发送文件 file_info_json = self.request.recv(8096) file_info = json.loads(file_info_json) filename = file_info.get("filename") filename_size = file_info.get("filename_size") filesize = os.path.getsize("put/" + filename) filesize = struct.pack("i", filesize) self.request.send(filesize) #发送文件大小 md5 = hashlib.md5() with open("put/" + filename,"rb") as f: f.seek(filename_size) for line in f: self.request.send(line) md5.update(line) # 写入要加密的东西 data = self.request.recv(8096) md5_val = md5.hexdigest() # 获取密文 self.request.send(md5_val.encode("utf8")) is_valid = self.request.recv(8096).decode("utf8") if is_valid == "203": print("传递成功,文件完整!") break else: print("文件上传失败!") break server = socketserver.ThreadingTCPServer(("192.168.13.226",8080),Myserver) server.serve_forever()
客户端:
import socket import os import json import struct import hashlib sock = socket.socket() sock.connect(("192.168.13.226",8080)) md5 = hashlib.md5() while 1: num = input("1.上传 2.下载") sock.send(num.encode("utf8")) num = int(num) if num == 1: filename = input("请输入要上传的文件名:") file_size = os.path.getsize("put/" +filename) file_info = { "filename": filename, "file_size": file_size, } file_info_json = json.dumps(file_info).encode("utf8") # 将字典序列化 sock.send(file_info_json) filename_size = sock.recv(8096) filename_size = struct.unpack("i", filename_size)[0] # 解包 if filename_size != 0: row1 = input("文件还未下载完毕,是否续传?(1&2)") if row1 == "2": filename_size = 0 #循环上传 md5 = hashlib.md5() with open("put/" + filename, "rb") as f: f.seek(filename_size) for line in f: sock.send(line) md5.update(line) # 写入要加密的东西 data = sock.recv(8096) md5_val = md5.hexdigest() # 获取密文 sock.send(md5_val.encode("utf8")) is_valid = sock.recv(8096).decode("utf8") if is_valid == "203": print("传递成功,文件完整!") else: print("文件上传失败!") elif num == 2: filename = input("请输入要下载的文件名:") if os.path.isfile("put/"+"%s副本"% filename): # 如果是存在的文件,返回True.否则返回False) row1 = input("文件还未下载完毕,是否续传?(1&2)") if row1 == "1": filename_size = os.path.getsize("put/"+"%s副本"% filename) # 返回path的大小 else: filename_size = 0 # ret = struct.pack("i", filename_size) #打包 # sock.send(ret) #发送已下载文件的大小 else: filename_size = 0 file_info = { "filename":filename, "filename_size":filename_size } file_info_json = json.dumps(file_info).encode("utf8") # 将字典序列化 sock.send(file_info_json) filesize = sock.recv(8096) #获取文件大小 filesize = struct.unpack("i", filesize)[0] # 解包 # 循环接收文件 with open("put/"+"%s副本"% filename, "ab") as f: # recv_data_length = 0 while filename_size < filesize: data = sock.recv(8096) filename_size += len(data) f.write(data) # MD5摘要 md5.update(data) # 写入要加密的的东西 # print("文件总大小:%s,已成功接收%s" % (filesize, recv_data_length)) sock.send(b"OK") # print(md5.hexdigest()) md5_val = md5.hexdigest() # 解密 client_md5 = sock.recv(8096).decode('utf8') if md5_val == client_md5: sock.send(b"203") print("接收成功!") os.rename("put/"+"%s副本"% filename,"put/"+filename) else: sock.send(b"204") print("接收失败!")
三丶进度条
import time import sys def progress_test(): bar_length = 10 # #号的长度 for percent in range(0, 101): hashes = '#' * int(percent / 100.0 * bar_length) spaces = ' ' * (bar_length - len(hashes)) sys.stdout.write("\rPercent: [%s] %d%%" % (hashes + spaces, percent)) sys.stdout.flush() time.sleep(0.05) #相隔多少秒执行一次 progress_test()
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:python各种推导式分析
- 网络编程相关知识点 2019-08-13
- python 之 面向对象(多态性、装饰器方法 内置函数补充) 2019-07-24
- 闯越自动签到demo版补充说明 2019-07-24
- day 35 补充 2019-05-22
- Python第二周总结 2019-04-30
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash