摘要

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

正文

粘包

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

  方案一:

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

  方案二:

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

#方案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. virtualbox+vagrant学习-3-Vagrant Share-1-简介

    Vagrant Share 通过 ngrok 内网穿透功能实现让全世界人可以访问虚拟机的服务 Vagrant Share允许你与世界上的任何人共享您的Vagrant环境,几乎支持你在任何网络环境中使用 ...

  2. leetcode 217. Contains Duplicate 287. Find the Duplicate Number 442. Find All Duplicates in an Array 448. Find All Numbers Disappeared in an Array

    后面3个题都是限制在1-n的,所有可以不先排序,可以利用巧方法做.最后两个题几乎一模一样. 217. Contains Duplicate class Solution { public: bool ...

  3. R语法:<<-为全局变量赋值

    例:在函数内部为全局变量赋值 all_predata_time <- data.frame(pd=0.1,Row=1,preRow=0,pt=0.1,stasid='1',InitDate='1 ...

  4. Oracle 数据库纯dos代码操作

    1. 安装成功后进入DOS界面操作 在进行以下操作时,需启动Oracle服务. A.进入sql界面:开始--运行--cmd:输入sqlplus 回车 提示输入正确的用户名和密码 B.开始—>所有 ...

  5. PAT乙级1001

    https://pintia.cn/problem-sets/994805260223102976/problems/994805325918486528 #include<bits/stdc+ ...

  6. FFMpeg笔记(二) 使用FFmpeg对视频进行编解码的一般流程

    1. 编码: 1.对编码资源的初始化 AVCodec* m_pVideoEncoder;// 特定编码器的参数信息 AVCodecContext* m_pVideoEncoderContext;// ...

  7. IOPS、带宽(band width)、吞吐量 (throughput)

    SAN和NAS存储一般都具备2个评价指标:IOPS和带宽(throughput),两个指标互相独立又相互关联.体现存储系统性能的最主要指标是IOPS.   IOPS (Input/Output Per ...

  8. UOJ#206. 【APIO2016】Gap(交互,乱搞)

    描述 提交 自定义测试 有 NN 个严格递增的非负整数 a1,a2,…,aNa1,a2,…,aN(0≤a1<a2<⋯<aN≤10180≤a1<a2<⋯<aN≤101 ...

  9. uniapp开发踩坑记录

    数组绑定class的问题 版本:v1.5.4 自定义了一个icon的组件,部分代码如下 <template> <text :class="[name, icon]" ...

  10. C语言学习记录_2019.02.05

    switch只能判断整数,而分段函数的判别是一个范围,我们无法用整数来表示范围 跟踪语句的方法: (1)debug调试 (2)printf( )语句跟踪 小套路:当循环次数很大时,可以先模拟较小次数的 ...