NO.8:自学python之路------并行socket网络编程
摘要
一到放假就杂事很多,这次的作业比较复杂,做了一个周,进度又拖了。不过结果还不错。
正文
粘包
在上一节中,如果连续发送过多数据,就可能发生粘包。粘包就是两次发送的数据粘在一起被接收,损坏了数据的完整性。解决方法有两种。
方案一:
在发送多个数据之间添加接收确认。这样在完成一次发送以后只有接收到另一端的确认以后才会开始新的发送,避免了粘包的发生。
方案二:
首先将发送数据的大小发送给另一端,另一端根据数据的大小接收。一次接收一次发送的数据量,这样也就避免了数据的粘包。例子。
#方案1
#server
f = open(path, 'wb')
for i in f:
server.socket.send(i)
f.close()
server.socket.recv(1024)
server.socket.send(b'发送完毕')
#client
recv_data = ''
while True:
data = client.socket.recv(1024)
if not data:
break
recv_data += data
client.socket.send(b'recv over')
other_data = client.socket.recv(1024)
#方案2
#server
size = os.path.getsize(path)
server.socket.send(size.encode())
server.socket.recv(1024)
f = open(path, 'wb')
for i in f:
server.socket.send(i)
f.close()
server.socket.send(b'发送完毕')
#client
size = client.socket.recv(1024)
client.socket.send(b'start')
recv_data = ''
recv_size = 0
while recv_size < size:
if size - recv_size < 1024:
single_size = size - recv_size
else:
single_size = 1024
data = client.socket.recv(single_size)
recv_size += len(data)
recv_data += data
other_data = client.socket.recv(1024)
FTP
一个简单的FTP过程主要包含以下几个步骤。
1.读取文件名
2.检测文件是否存在
3.打开文件
4.检测文件大小,文件名
5.发送文件大小 md5值给客户端
6.等待客户端确认
7.开始边读取数据边发送数据
8.md5确认
具体例子。
服务器
# 服务器端
import socket
import os
import hashlib server = socket.socket()
server.bind(('localhost', 9999))
server.listen() while True:
conn, addr = server.accept()
print('new conn:', addr)
while True:
data = conn.recv(1024)
data = data.decode()
if not data:
print('客户端已断开')
break
cmd, filename = data.split()
print(filename)
if os.path.isfile(filename):
f = open(filename, 'rb')
m = hashlib.md5()
file_size = os.stat(filename).st_size
print(file_size)
conn.send(str(file_size).encode('utf-8'))
conn.recv(1024)
for line in f:
m.update(line)
conn.send(line)
print('md5:', m.hexdigest())
f.close()
conn.send(m.hexdigest().encode('utf-8'))
客户端
# 客户端
import socket
import hashlib client = socket.socket()
client.connect(('localhost', 9999)) while True:
cmd = input('>>').strip()
if len(cmd) == 0:
continue
if cmd.startswith('get'):
client.send(cmd.encode('utf-8'))
cmd_res_size = client.recv(1024) # 接收长度
print('文件大小 %s' % (cmd_res_size.decode()))
client.send('准备完毕,开始发送数据'.encode('utf-8'))
recv_size = 0
file_name = cmd.split()[1]
f = open(file_name + '.new', 'wb')
m = hashlib.md5()
while recv_size < int(cmd_res_size.decode()):
if int(cmd_res_size.decode()) - recv_size > 1024:
size = 1024
else:
size = int(cmd_res_size.decode()) - recv_size
data = client.recv(size)
recv_size += len(data) # 读取每次接收的数据
f.write(data)
m.update(data)
#print(recv_size)
else:
file_md5 = m.hexdigest()
print('文件接收完毕', recv_size)
f.close()
recv_md5 = client.recv(1024)
print(file_md5, recv_md5.decode())
client.close()
SocketServer
SocketServer是Python的一个包,它在socket的基础上封装,可以更加简单的完成并发处理。
socketserver.TCPServer 继承BaseServer,完成TCP
socketserver.UDPServer 继承TCPServer,完成UDP
socketserver.UnixStreamServer 继承TCPServer,完成Unix的TCP
socketserver.UnixDatagramServer 继承UDPServer,完成Unix的UDP
使用socketserver的步骤:
1.创建一个请求处理类,并且这个类要继承BaseRequestHandler,并且需要重写父类中的Handle()方法。
2.实例化一个Server类,并且传递Server ip和1中创建的请求处理类给它。
3.server.handle_request()只处理一个请求 server.server_forever()处理多个请求,永久执行。
4.调用server_close()关闭它。
BaseServer中的常用方法,例子。
fileno() # 返回文件描述符
handle_request # 处理单个请求
serve_forever(poll_interval=0.5) # 一直运行直到收到shutdown()请求,每poll_interval检查一次,后调用service_actions()结束
service_actions() # 结束操作
shutdown() # 停止信号
server_close() # 清除server
address_family # 地址簇
RequestHandlerClass # 请求处理类
server_address # ip地址
socket # 同socket
self.allow_reuse_adress # 允许重用地址 socket中socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
socket_type # socket使用的协议类型
self.setup() # 请求来之前 self.handle() # 请求来时 self.finish() # 请求处理之后
作业
1.用户加密认证
2.允许多个用户登陆
3.每个用户有自己的家目录,不能互相访问
4.对用户进行磁盘配额,可用空间不同
5.允许用户在ftp_server上随意切换目录
6.允许用户查看当前目录文件
7.允许用户上传下载文件,保证文件一致性
8.传输过程显示进度条
NO.8:自学python之路------并行socket网络编程的更多相关文章
- Python全栈【Socket网络编程】
Python全栈[socket网络编程] 本章内容: Socket 基于TCP的套接字 基于UDP的套接字 TCP粘包 SocketServer 模块(ThreadingTCPServer源码剖析) ...
- Python面向对象进阶和socket网络编程-day08
写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...
- Python面向对象进阶和socket网络编程
写在前面 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __init__(self ...
- Python之旅Day8 socket网络编程
socket网络编程 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可.soc ...
- python学习之路-9 socket网络编程
socket基础 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. so ...
- NO.7:自学python之路------类的方法、异常处理、socket网络编程
引言 我visual studio 2017就算体积巨大.启动巨慢.功能简陋也不会安装PyCharm的,嘿呀,真香.好吧,为了实现socket网络编程,更换了软件. 正文 静态方法 只是在名义上归类管 ...
- Python之路,Day8 - Socket编程进阶
Python之路,Day8 - Socket编程进阶 本节内容: Socket语法及相关 SocketServer实现多并发 Socket语法及相关 socket概念 socket本质上就是在2台 ...
- 自学Python之路
自学Python之路[第一回]:初识Python 1.1 自学Python1.1-简介 1.2 自学Python1.2-环境的搭建:Pycharm及python安装详细教程 1.3 ...
- 自学Python之路-Python核心编程
自学Python之路-Python核心编程 自学Python之路[第六回]:Python模块 6.1 自学Python6.1-模块简介 6.2 自学Python6.2-类.模块.包 ...
随机推荐
- elasticsearch5.5安装
beat -------- kafka -------- logstash---------------elasticsearch--------------kibana beat配置文件 [roo ...
- ubuntu16.04常见的问题解决方案
问题一:关于咖啡主机和其他服务器厂商和个人虚拟机VM10安装ubuntu16.04 ubuntu16.04默认是没有root用户的,要想有必须要通过用户创建,通常安装ubuntu16.04会有个让你创 ...
- ZOJ 3992 One-Dimensional Maze(思维题)
L - One-Dimensional Maze Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & % ...
- 倒计数锁存器(CountDown Latch)和 CyclicBarrier(同步屏障)
倒计数锁存器(CountDown Latch)是异常性障碍,允许一个或多个线程等待一个或者多个其他线程来做某些事情. public static long time(Executor executor ...
- css选择器,样式表导入
css笔记1.选择器(selecter)共9种 a.类型选择器 p{},body{} b.后代选择器 p h1{} c.ID选择 #idname{} d.类选择 .classname{} e.通用选择 ...
- 什么是X86和X86-64
X86的定义 X86是一个Intel或AMD通用计算机系列的标准编号缩写,也是32位微处理器架构的一种,也标识一套通用的计算机指令集. X86-64的定义 X86-64,简称X64,是一个Intel或 ...
- jQuery----each()方法
jquery中有隐式迭代,不需要我们再次对某些元素进行操作.但是如果涉及到不同元素有不同操作,需要进行each遍历.本文利用10个li设置不同的透明度的案例,对each方法进行说明. 语法: $(元素 ...
- day 88 Vue学习之八geetest滑动验证
本节目录 一 geetest前端web中使用 二 xxx 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 geetest前端web中使用 下载gt文件,官网地址,下面我 ...
- 【转】WCF设置拦截器捕捉到request和reply消息
原文:https://www.cnblogs.com/yanglang/p/7063743.html 我们需要拦截消息,并把消息打印出来,那么我们就需要一个拦截器,叫做MessageInspector ...
- 【转】 不需要任何权限获得Android设备的唯一ID
不需要任何权限获得Android设备的唯一ID,权限android设备id 这个问题来自于Is there a unique Android device ID? 我对这个问题的答案做了整理,包括将另 ...