摘要

  一到放假就杂事很多,这次的作业比较复杂,做了一个周,进度又拖了。不过结果还不错。

正文

粘包

  在上一节中,如果连续发送过多数据,就可能发生粘包。粘包就是两次发送的数据粘在一起被接收,损坏了数据的完整性。解决方法有两种。

  方案一:

    在发送多个数据之间添加接收确认。这样在完成一次发送以后只有接收到另一端的确认以后才会开始新的发送,避免了粘包的发生。

  方案二:

    首先将发送数据的大小发送给另一端,另一端根据数据的大小接收。一次接收一次发送的数据量,这样也就避免了数据的粘包。例子。

#方案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网络编程的更多相关文章

  1. Python全栈【Socket网络编程】

    Python全栈[socket网络编程] 本章内容: Socket 基于TCP的套接字 基于UDP的套接字 TCP粘包 SocketServer 模块(ThreadingTCPServer源码剖析) ...

  2. Python面向对象进阶和socket网络编程-day08

    写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...

  3. Python面向对象进阶和socket网络编程

    写在前面 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __init__(self ...

  4. Python之旅Day8 socket网络编程

    socket网络编程 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可.soc ...

  5. python学习之路-9 socket网络编程

    socket基础 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. so ...

  6. NO.7:自学python之路------类的方法、异常处理、socket网络编程

    引言 我visual studio 2017就算体积巨大.启动巨慢.功能简陋也不会安装PyCharm的,嘿呀,真香.好吧,为了实现socket网络编程,更换了软件. 正文 静态方法 只是在名义上归类管 ...

  7. Python之路,Day8 - Socket编程进阶

    Python之路,Day8 - Socket编程进阶   本节内容: Socket语法及相关 SocketServer实现多并发 Socket语法及相关 socket概念 socket本质上就是在2台 ...

  8. 自学Python之路

    自学Python之路[第一回]:初识Python    1.1 自学Python1.1-简介    1.2 自学Python1.2-环境的搭建:Pycharm及python安装详细教程    1.3  ...

  9. 自学Python之路-Python核心编程

    自学Python之路-Python核心编程 自学Python之路[第六回]:Python模块       6.1 自学Python6.1-模块简介    6.2 自学Python6.2-类.模块.包  ...

随机推荐

  1. kubeadm init 时从本地私有仓库下载镜像

    #kubeadm init 时从本地私有仓库下载镜像 images=( gcr.io/google_containers/kube-proxy-amd64:v1.6.1 gcr.io/google_c ...

  2. ethereumjs/ethereumjs-common-3-test

    查看test能够让你更好滴了解其API文档的使用 ethereumjs-common/tests/chains.js const tape = require('tape') const Common ...

  3. Java 中 Emoji 的正则表达式

    一.emoji 的范围 查阅维基百科中 emoji 的说明 1. 杂项符号及图形 杂项符号及图形一共有768个字符,范围为: U+1F300 - U+1F5FF,在 Java 中正则表达式为: &qu ...

  4. 初识Qt鼠标、键盘事件及定时器和随机数

    1.新建Qt Gui应用,项目名称为“myEvent”,基类名称为QWidget,类名称为Widget. 2.widget.h文件中添加以下代码,该段代码中包含了三个事件函数和一个槽函数 privat ...

  5. Spring AOP源码分析(三)创建AOP代理

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 目录 一.获取增强器 1. 普通增强器的获取 2. 增加同步实例化增强 ...

  6. C语言程序设计I—第十周教学

    第十周教学总结(04/11-10/11) 教学内容 第4章 循环结构-while /do-while语句 4.1用格里高利公式求π的近似值,4.2 统计一个整数的位数 课前准备 在蓝墨云班课发布资源: ...

  7. UCOSii和Linux的区别和联系

    UCOSii和Linux的区别和联系 想通过UCOSii来理解Linux的系统架构,故参考一些资料,简单整理了一下UCOSii和Linux的区别和联系,以此来更好的学习Linux. 其具体对比如下: ...

  8. hbase-列存储动态数据库

    1)   HBase是什么? HBase是建立在Hadoop文件系统之上的分布式面向列的数据库.它是一个开源项目,是横向扩展的. HBase是一个数据模型,类似于谷歌的大表设计,可以提供快速随机访问海 ...

  9. kNN分类算法实例1:用kNN改进约会网站的配对效果

    目录 实战内容 用sklearn自带库实现kNN算法分类 将内含非数值型的txt文件转化为csv文件 用sns.lmplot绘图反映几个特征之间的关系 参考资料 @ 实战内容 海伦女士一直使用在线约会 ...

  10. 【安装Ecshop2.7.2网站(LAMP环境)】--实践

    LAMP : Linux + Apache + Mysql + PHPEcshop2.7.2 注意:在输入命令过程中,学会用tab键补全命令,不要对着照抄,很容易出错. 前置:A:先设置虚拟机中的CD ...