网络编程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 ...
随机推荐
- 联想E440问题:点击鼠标时,弹出“无法连接synaptics定点装置驱动程序”错误
笔记本:Levono E440 问题描述: 在控制面板中,点击鼠标时,弹出“无法连接synaptics定点装置驱动程序”错误,如何解决? 即使在安装联想的驱动后,也没办法解决 解决步骤: 1. ...
- nginx-1.2.7+tcp_proxy_module负载均衡配置
对于安装方面不清楚的,可移步 nginx + tcp_proxy_module的安装 参考nginx_tcp_proxy_module的readme文件,对每个定义项都做了详细的描述,tcp{...} ...
- freeswitch录音功能
首先备份/usr/local/freeswitch/conf/dialplan/default.xml . 然后vi编辑default.xml ,在 <extension name=" ...
- 新标准C++程序设计读书笔记_运算符重载
形式 返回值类型 operator 运算符(形参表) { …… } 运算符重载 (1)运算符重载的实质是函数重载(2)可以重载为普通函数,也可以重载为成员函数 class Complex { publ ...
- jquery的input:type=file实现文件上传
<!DOCTYPE html> <html> <head> <title>html5_2.html</title> <style> ...
- 把一个project相关的jar放到project的lib文件夹中
例如你有一个project名为xxx,/xxx 文件夹中有src.bin.等等,然后你手工创建一个lib文件夹,这样你就把解压出来的第三方lib(jar包,含javadoc)都放到lib文件夹中,这样 ...
- linux学习笔记29---命令watch
watch是一个非常实用的命令,基本所有的Linux发行版都带有这个小工具,如同名字一样,watch可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行.在Linux下,watch是周期性的执行下个 ...
- linux--jdk安装与配置
此处以centos下jdkjdk1.8.0_161安装(此处为rpm安装事例)为例 1.java官网下载页找到对应版本的jdk下载链接地址 2.下载对应版本的rmp包到服务器,执行如下指令: wget ...
- hdu3879 Base Station 最大权闭合子图 边权有正有负
/** 题目:hdu3879 Base Station 最大权闭合子图 边权有正有负 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879 题意:给出n个 ...
- C++ 类的继承五(类继承中的static关键字)
//类继承中的static关键字 #include<iostream> using namespace std; /* 派生类中的静态成员 基类定义的静态成员,将被所有派生类共享 根据静态 ...