网络编程4 网络编程之FTP上传简单示例&socketserver介绍&验证合法性连接
今日大纲:
1.FTP上传简单示例(详细代码)
2.socketserver简单示例&源码介绍
3.验证合法性连接//[秘钥加密(urandom,sendall)(注意:中文的!不能用)]
内容回顾:
(1)TCP(流)两种黏包现象
1.连续(两次发送的时间间隔很短暂)发送(send)两个小包,被优化算法nagle,
给合并到了一起,造成了黏包
2.一次性接收的数据,并没有将发送的数据完全接受完,第二次接收数据的时候,
会把第一次剩余的数据给接收过来
UDP不会发生黏包现象, (2)解决方案:
思想:先接收长度,再接收数据(根据长度拿取数据)
两种解决方案:
1.发送真实数据之前,先发送数据的长度,接收方接收到长度之后,先回复一个确认信息,
发送端再发送真实的数据,接收方按照先发送来的数据长度来接收后面的真实数据.
2.struct
A:struct.pack('i',数字)
B:struct.unpack('i',bytes) 元组类型,需要索引取数据 (3)缓冲区:解决代码的耦合性(从内存中开辟出的一块空间)
输出缓冲区
输入缓冲区
conn,addr=>长连接 (4)
subprocess模块
注意命令:用gbk进行解码处理,因为windows中文版,默认编码是gbk
1.FTP上传简单示例(详细代码)
服务端:
#重点案例
import socket
import json
import struct server=socket.socket()
server.bind(('127.0.0.1',8001))
server.listen()
conn,addr=server.accept() #首先接收文件的描述信息的长度
struct_data_len=conn.recv(4)
data_len=struct.unpack('i',struct_data_len)[0] #通过文件信息的长度将文件的描述信息全部接收
print('data_len>>>',data_len)
file_info_bytes=conn.recv(data_len)
#将字符串转换成bytes类型
#将文件描述信息转换为字典类型,一遍操作
file_info_json=file_info_bytes.decode('utf-8')
file_info_dict=json.loads(file_info_json)#{'file_name': 'aaa.mp4', 'file_size': 24409470} print(file_info_dict)
#统计每次接收的累计长度
recv_sum=0 with open('F:\S18\gg\aaa.mp4','wb') as f:
while 1:
every_recv_data=conn.recv(1024)
print()
#问题:文件名称不知道这样写不合适,
#所以,文件需要先发送文件信息
客户端:
#需求:客户端给服务端上传文件,一句给的文件信息保存文件
import os
import json
import struct
import socket client=socket.socket()
client.connect(('127.0.0.1',8001)) file_size=os.path.getsize(r'F:\Python_workspace_S18\week7\day29\02 ftp上传简单示例\aaa.mp4')#首先统计数据的长度 #传文件的信息,大小,文件名
file_info={
'file_name':'aaa.mp4', #文件的名称
'file_size':file_size, #文件的大小
#路径等等
#客户端给服务端传递文件,客户端需要循环接收数据大小,
# 还有文件名,还有服务端的那个路径下,这里没有设置服务端的路径(参考网上设置)
# 或者可能老师后期可能讲解
}
#这里pickle用的少,所以用json比较多,我们这里用json
#思考:字典发送给服务端,转换成bytes类型的,这里必须用json #由于字典无法直接转换成bytes类型的数据,所以需要json来将字典转换为
file_info_json=json.dumps(file_info) #将字符串转换成bytes类型的数据
file_info_byte=file_info_json.encode('utf-8') #为了防止黏包现象,将文件描述信息的长度打包后和文件的描述信息的数据一起发送过去
data_len=len(file_info_byte)
data_len_struct=struct.pack('i',data_len) #发送文件描述信息
client.send(data_len_struct+file_info_byte) #定义一个变量,=0,作为每次读取文件的长度的累计值
sum=0
#打开的aaa.mp4文件,rb的形式,
with open('aaa.mp4','rb') as f:
#循环读取文件内容
while sum<file_size: #等于的时候已经读完了
##每次读取文件的内容,每次读取1024b字节
every_read_data=f.read(1024) #每次读1024个字节,
#当最后一次的数据不够1024的时候,接收不够的也是不会报错的
sum+=len(every_read_data)
client.send(every_read_data)#每次发送1024个字节
#打开数据文件都是只有一行
#read可以控制读取的数据的长度
#readline不可以控制读取的数据的长度
#思考:数据的长度问题?
#死循环怎么结束这个循环?
#锻炼自己的逻辑能力
#数据读完怎么跳出来?
#统计每次读的数据的长度
#首先统计数据的长度os模块
重点回顾&补充
import os
file_size=os.path.getsize(r'F:\Python_workspace_S18\week7\day29\02 ftp上传简单示例\aaa.mp4')
print(file_size) # file_info = {
'file_name':'aaa.mp4',
'file_size':file_size,
} by_dic1 = bytes(str(file_info)+'中国',encoding='gbk')#b"{'file_name': 'aaa.mp4', 'file_size': 4966541}"
by_dic = bytes(str(file_info)+'中国',encoding='utf-8')#b"{'file_name': 'aaa.mp4', 'file_size': 4966541}" print(by_dic1)
print(by_dic) k=os.urandom(4)
print(k,type(k),len(k)) s=bytes('中国',encoding='utf-8')
s=bytes([1,2,3,4])
print(s,type(s)) '''
结果:
4966541
b"{'file_name': 'aaa.mp4', 'file_size': 4966541}\xd6\xd0\xb9\xfa"
b"{'file_name': 'aaa.mp4', 'file_size': 4966541}\xe4\xb8\xad\xe5\x9b\xbd"
b'\xd7n+y' <class 'bytes'> 4
b'\x01\x02\x03\x04' <class 'bytes'>
'''
2.socketserver简单示例&源码介绍
简单示例
服务端:
#原理:就是一个简单模块的简单使用,不要想的太难
#这个服务端启用一个,可以启动多个客户端进行同时交流
#注意:这个是先从客户端向服务端发送消息,再从服务端回客户端消息
import socketserver
class Myserver(socketserver.BaseRequestHandler): #定义类
def handle(self):
while 1:
from_client_msg=self.request.recv(1024) #self.request=conn
print(from_client_msg.decode('utf-8'))
msg=input('服务端说:')
self.request.send(msg.encode('utf-8'))
if __name__=='__main__':
ip_port=('127.0.0.1',8001)
server=socketserver.ThreadingTCPServer(ip_port,Myserver)
#调用模块的方法(线程TCP服务)
#参数:接口&自定义继承类
#server相当于一个对象,也就是创建了这么个对象
server.serve_forever()
#而这里server对象调用serve_forever方法,相当于是开启永远的服务 '''
#推荐思路:(源码问题)
socketserver源码,要练习看一下.
python怎么看源码(百度试着看看教程)
'''
客户端:
import socket
client=socket.socket()
client.connect(('127.0.0.1',8001)) while 1:
msg=input('客户端说>>>')
client.send(msg.encode('utf-8')) from_server_msg=client.recv(1024)
print(from_server_msg.decode('utf-8'))
源码介绍:(这个地方就是提升自己的地方)
超哥blog:(主要是socketserver的源码解读)
https://www.cnblogs.com/clschao/articles/9593164.html
女神blog:
解读python中socket的源码(http://www.cnblogs.com/Eva-J/p/5081851.html)
3.验证合法性连接//[秘钥加密(urandom,sendall)(注意:中文的!不能用)]
网络编程4 网络编程之FTP上传简单示例&socketserver介绍&验证合法性连接的更多相关文章
- python 网络编程粘包解决方案2 + ftp上传 + socketserver
一.struct 神奇的打包工具 struct 代码: import struct num = 156 #将int类型的数据打包成4个字节的数据 num_stru = struct.pack('i', ...
- python网络编程--FTP上传文件示例
1.基础版(供学习了解原理使用,low) server服务端 import socket import struct import json server = socket.socket() ip_p ...
- iOS开发之网络编程--5、NSURLSessionUploadTask+NSURLSessionDataDelegate代理上传
前言:关于NSURLSession的主要内容快到尾声了,这里就讲讲文件上传.关于文件上传当然就要使用NSURLSessionUploadTask,这里直接讲解常用的会和代理NSURLSessionDa ...
- java网络编程(7)——利用tcp实现文件上传
其实客户端与服务端通讯的道理都是一样的,都是通过输入与输出这两个流,那么实现文件上传也就是同样的,客户端把文件读到文件流,服务端用文件流来接受,然后写到一个文件中,这样子就实现了文件上传,文件拷贝也是 ...
- java 网络编程(五)Socket多线程上传文件
客户端: package cn.sasa.socketUploadFileDemo; import java.io.FileInputStream; import java.io.IOExceptio ...
- SpringMVC+Spring+MyBatis 整合与图片上传简单示例
一.思路: (一) Dao层: 1. SqlMapConfig.xml,空文件即可.需要文件头.2. applicationContext_dao.xml. a) 数据库连接池b) SqlSessio ...
- Spring MVC 文件上传简单示例(form、ajax方式 )
1.Form Upload SpringMVC 中,文件的上传是通过 MultipartResolver 实现的,所以要实现上传,只要注册相应的 MultipartResolver 即可. Multi ...
- FTP上传文件时 System.Net.WebException: 基础连接已经关闭: 接收时发生错误。
在c#中使用HttpWebRequest时,频繁请求一个网址时,过段时间就会出现“基础连接已经关闭: 接收时发生意外错误”的错误提示.将webRequest的属性设置成下面的,经测试可以解决.Syst ...
- python之路--FTP 上传视频示例
# 服务端 import json import socket import struct server = socket.socket() server.bind(('127.0.0.1',8001 ...
随机推荐
- FIFO、LRU、OPT页面调度算法及样例
网上非常多介绍3种页面置换算法的样例和过程是不对的, 本文依据<操作系统概念>第七版对三种算法做介绍,并给出正确的样例以验证算法. 一.FIFO先进先出页面置换算法,创建一个FIFO队列来 ...
- CentOS7:gdb出现没有调试信息:Missing Separate debuginfos
现在刚刚开始学习用gdb调试程序,结果:在centos下,出现这样的错误: gdb在调试程序时候提示 Missing separate debuginfos, use: debuginfo-insta ...
- Unity中差乘判断目标是否在左边或右边
使用差乘判断左右一般是比较差乘的y,小于0是左,大于0是右.特殊情况可以用其他分量来比较 默认情况: var cross = Vector3.Cross(lhsObject.transform.pos ...
- python学习之split()
定义: Python split()通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串 语法: str.split(str="", num=st ...
- mongodb数据库shell
mongoexport -d mofangdb -c log_user_access_index --type=csv -f _id,uid,page,date -o log_user_access_ ...
- unittest最详细的解说
转自:http://www.imooc.com/article/257230 一.什么是unittest unittest是Python单元测试框架,类似于JUnit框架. unittest中有4个重 ...
- 跟着百度学PHP[14]-PDO之Mysql的事务处理1
事务处理:在实际案例当中干一件事的mysql语句(好比转账,小一同学转账100,小二同学收账,在mysql当中小一就要减去转账的钱,小二就要增加100快)倘若该语句执行过程中有任何一条的sql语句出错 ...
- 转 java调用php的webService
1.首先先下载php的webservice包:NuSOAP,自己到官网去下载,链接就不给出来了,自己去google吧 基于NoSOAP我们写了一个php的webservice的服务端,例子如下: ...
- mysql—Access denied for user 'root'@'localhost' (using password:NO)
安装mysql未设置初始密码,登录提示Access denied for user 'root'@'localhost' (using password:NO): 解决方案: sudo /etc/i ...
- php 合并数组的方法 非array_merge
Array ( [0] => Array ( [max] => 50 [date] => 2016-01-07 ) [1] => Array ( [max] => 100 ...