摘要

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

正文

粘包

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

  方案一:

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

  方案二:

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

#方案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. shell基础--字符串和变量的操作

    一.统计字符串长度 1.wc –L [root@~_~day4]# echo "hello" | wc -L 5 2.expr length string [root@~_~day ...

  2. PHP学习笔记一:谁动了你的mail(),PHP?

    PHP编写邮件发送的函数时候,会出现一个很奇怪的问题,那就是: Warning: mail(): Failed to connect to mailserver at "localhost& ...

  3. 03.Java语言基础

    Java程序的组成 关键字,标识符,注释,变量,语句,表达式,数组,方法 关键字 Java语言内部使用了的一些用于特殊用途的词汇,那么在程序中用户不能使用.语言本身保留了一些词汇用于语言的语法等用途. ...

  4. ES6新特性3:函数的扩展

    本文摘自ECMAScript6入门,转载请注明出处. 一.函数参数默认值 1. ES6允许为函数的参数设置默认值,即直接写在参数定义的后面. function log(x, y = 'World') ...

  5. ROS計算圖級(通訊架構)

    查看节点构成的计算图 rqt_graph 节点node就是运行了的可执行文件

  6. pom xml testng

    <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId ...

  7. Unity3D游戏开发从零单排(三) - 极速创建狂拽酷炫的游戏地形

    提要 在Unity工作流程内,地形是一个必不可少的重要元素.不论是游戏或虚拟现实都会使用到各种类型的地形效果,在这个教学中我们须要了解到地形的制作基本概念与,当中对于Unity的地形操作部分须要大量的 ...

  8. 【NodeJs】Nodejs系列安装

    nodejs安装—npm安装—(其他基于这俩项的另写) windows环境 1)nodejs安装 ①下载对应系统版本的Node.js:https://nodejs.org/en/download/ e ...

  9. VMware Tools安装方法及解决无法全屏显示问题

    环境:VMware8.0虚拟机        ubuntu:12.04 在刚安装完ubuntu后,屏幕不能全屏显示,此时: 1.安装VMware Tools 步骤: 1.1     进入ubuntu系 ...

  10. spark练习——影评案例

    第一次写博客,新人上路,欢迎大家多多指教!!! ---------------------------------------------------------------------分割线---- ...