书签 分享 收藏 举报 版权申诉 / 47
上传文档赚钱

类型Python程序设计课件第12章网络编程和多线程编程.pptx

  • 上传人(卖家):晟晟文业
  • 文档编号:3713703
  • 上传时间:2022-10-06
  • 格式:PPTX
  • 页数:47
  • 大小:281.96KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《Python程序设计课件第12章网络编程和多线程编程.pptx》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    Python 程序设计 课件 12 网络 编程 多线程
    资源描述:

    1、 网络编程基础网络编程基础 TCP编程编程 多线程编程多线程编程第12章 网络和多任务编程参考书目Python 程序设计目录 网络编程基础网络编程基础 TCP编程编程 多线程编程多线程编程这里说明图片内容 网络编程基础网络编程基础 TCP编程编程 多线程编程多线程编程目录这里说明图片内容 网络编程基础1 IP 地址IP 地址就是标识网络中设备的一个地址,类比家庭地址。IP 地址分为两类:IPv4 和 IPv6。目前使用的IP地址 由点分十进制组成(比如:192.168.247.1)IPv4 未来使用的IP地址 由冒号十六进制组成fe80:c0be:39:4cb4:3d21%30)IPv6网络编

    2、程基础1 IP 地址IP 地址的作用是标识网络中唯一的一台设备的,也就是说通过IP地址能够找到网络中某台设备。查看 IP 地址方式:使用 ifconfig 命令Linux 和 mac OS 使用 ipconfig 命令Windows检查网络是否正常使用,通常是在命令提示符中下使用ping 命令。比如:ping 61.135.169.121或者ping 。文件相关的基本概念2端口与端口号 传输数据的通道,好比教室的门 作用就是给运行的应用程序提供传输数据的通道。端口 对端口进行了编号,好比现实生活中的门牌号 作用是用来区分和管理不同端口的,通过端口号能找到唯一个的一个端口。端口号端口和端口号的关

    3、系:端口号可以标识唯一的一个端口。文件相关的基本概念2端口与端口号 指众所周知的端口号,范围从0到1023 一般固定分配给一些服务,比如21端口分配给FTP(文件传输协议)服务知名端口号 一般程序员开发应用程序使用端口号称为动态端口号,范围是从1024到65535。如果程序没有设置端口号,操作系统会在范围内随机生成。当运行的程序退出时,所占用的这个端口号就会被释放。动态端口号端口号的分类:文件相关的基本概念3 TCP数据不能随便发送,在发送之前还需要选择一个对应的传输协议,保证程序之间按照指定的传输规则进行数据的通信,即TCP。TCP 的英文全拼(Transmission Control Pr

    4、otocol)简称传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议。比如:文件下载,浏览器上网。TCP通信步骤:1)创建连接2)传输数据3)关闭连接TCP 的特点:1)面向连接2)可靠传输文件相关的基本概念4 Socket(套接字)socket(简称 套接字)是进程之间通信一个工具,好比现实生活中的插座socket 的作用是负责进程之间的网络数据传输,好比数据的搬运工。socket socket 使用场景:只要跟网络相关的应用程序或者软件都使用到使用场景:只要跟网络相关的应用程序或者软件都使用到了了socketsocket。比如即时聊天工具:。比如即时聊天工具:QQQQ、微

    5、信和浏览器。、微信和浏览器。文件相关的基本概念4 Socket(套接字)send和recv分别是指利用Socket在客户端与服务器端的数据发送和接收,send和recv的底层工作原理:1.TCP socket的发送和接收缓冲区2.send原理剖析 应用程序把发送的数据先写入到发送缓冲区应用程序把发送的数据先写入到发送缓冲区(内存中的一片空间内存中的一片空间),再由操作系统控制网卡把发送缓冲区的数据发送给服务端网卡再由操作系统控制网卡把发送缓冲区的数据发送给服务端网卡3.recv原理剖析 调用操作系统接口,由操作系统通过网卡接收数据,把接收的数据调用操作系统接口,由操作系统通过网卡接收数据,把接

    6、收的数据写入到接收缓冲区写入到接收缓冲区(内存中的一片空间),应用程序再从接收缓存内存中的一片空间),应用程序再从接收缓存区获取客户端发送的数据。区获取客户端发送的数据。网络编程基础网络编程基础 TCP编程编程 多线程编程多线程编程目录这里说明图片内容 TCP编程Socket分为客户端和服务器。客户端Socket用于建立与服务端Socket的连接,服务端Socket用于等待客户端Socket的连接。因此,在使用客户端Socket之前,必须建立服务端Socket。在Python语言中创建Socket服务端程序,需要使用Socket模块中的socket类。TCP编程TCP网络应用程序的注意以下2点

    7、:1)进行通信的时候必须要先建立连接。TCPTCP客户端程序一般不需要绑定端口号,因为客户端是主动发起建立连接的。客户端程序一般不需要绑定端口号,因为客户端是主动发起建立连接的。TCP TCP 服务端程序必须绑定端口号,否则客户端找不到这个服务端程序必须绑定端口号,否则客户端找不到这个 TCP TCP 服务端程序。服务端程序。listenlisten后的套接字是被动套接字,只负责接收新的客户端的连接请求,不能后的套接字是被动套接字,只负责接收新的客户端的连接请求,不能收发消息。收发消息。2)连接成功后,TCP 服务器端程序会产生一个新的套接字,收发客户端消息使用该套接字。关闭关闭 accept

    8、 accept 返回的套接字意味着和这个客户端已经通信完毕。返回的套接字意味着和这个客户端已经通信完毕。关闭关闭 listen listen 后的套接字意味着服务端的套接字关闭了,会导致新的客户端后的套接字意味着服务端的套接字关闭了,会导致新的客户端不能连接服务端,但是之前已经接成功的客户端还能正常通信。不能连接服务端,但是之前已经接成功的客户端还能正常通信。TCP编程1 TCP通信流程TCP编程2 创建TCP客户端程序主动发起建立连接请求的是客户端程序。编写TCP客户端程序:首先要导入socket模块:import socket其次是创建客户端 socket 对象:socket.socket

    9、(AddressFamily,Type)AddressFamily 表示IP地址类型,分为IPv4和IPv6 Type 表示传输协议类型TCP编程2 创建TCP客户端程序客户端创建方法:1.connect(host,port)表示和服务端套接字建立连接 host是服务器ip地址 port是应用程序的端口号2.send(data)表示发送数据,data是二进制数据3.recv(buffersize)表示接收数据,buffersize是每次接收数据的长度TCP编程2 创建TCP客户端程序本例实现了一个客户端Socket应用,该应用发送字符串,然后服务端返回数据,最后将这些数据输出到网络调试的终端上

    10、。import socketif _name_=_main_:#创建tcp客户端套接字#1.AF_INET:表示ipv4#2.SOCK_STREAM:tcp传输协议 tcp_client_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#和服务端应用程序建立连接 tcp_client_socket.connect(192.168.131.62,8080)#代码执行到此,说明连接建立成功#准备发送的数据 send_data=服务端,我是爱你的,请接受我吧!.encode(gbk)TCP编程2 创建TCP客户端程序本例实现了一个客户端S

    11、ocket应用,该应用发送字符串,然后服务端返回数据,最后将这些数据输出到网络调试的终端上。#发送数据 tcp_client_socket.send(send_data)#接收数据,这次接收的数据最大字节数是1024 recv_data=tcp_client_socket.recv(1024)#返回的直接是服务端程序发送的二进制数据 print(recv_data)#对数据进行解码 recv_content=recv_data.decode(gbk)print(接收服务端的数据为:,recv_content)#关闭套接字 tcp_client_socket.close()运行结果:bxb0 x

    12、aexc4xe3xd4xdaxbfxdaxa3xacxd7xecxc4xd1xbfxaaxa3xa1接收服务端的数据为:爱你在口,嘴难开!TCP编程3 创建TCP服务器端程序等待接受连接请求的是服务端程序。编写TCP服务端程序:首先要导入socket模块:import socket其次是创建服务端 socket 对象:socket.socket(AddressFamily,Type)AddressFamily 表示IP地址类型,分为IPv4和IPv6 Type 表示传输协议类型TCP编程3 创建TCP服务器端程序服务端创建过程:1.bind(host,port)表示绑定端口号,host 是 i

    13、p 地址,port 是端口号,ip 地址一般不指定,表示本机的任何一个ip地址都可以。2.listen(backlog)表示设置监听,backlog参数表示最大等待建立连接的个数。3.accept()表示等待接受客户端的连接请求4.send(data)表示发送数据,data 是二进制数据5.recv(buffersize)表示接收数据,buffersize 是每次接收数据的长度TCP编程3 创建TCP服务器端程序创建TCP服务端套接字,设置端口号为8989,设置监听,准备接受客户端发来的数据,并显示客户端的IP和端口号,演示TCP 服务端程序。import socketif _name_=_m

    14、ain_:#创建TCP服务器端套接字 tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#设置端口号复用,让程序退出端口号立即释放 tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)#给程序绑定端口号 tcp_server_socket.bind(,8989)#设置监听#128:最大等待建立连接的个数,提示:目前是单任务的服务端,同一时刻只能服务于一个客户端,后续使用多任务能够让服务端同时服务于多个客户端,#不需要让客户

    15、端等待建立连接 tcp_server_socket.listen(128)TCP编程3 创建TCP服务器端程序创建TCP服务端套接字,设置端口号为8989,设置监听,准备接受客户端发来的数据,并显示客户端的IP和端口号,演示TCP 服务端程序。#等待客户端建立连接的请求,只有客户端和服务端建立连接成功代码才会解阻塞,代码才能继续往下执行#1.专门和客户端通信的套接字:service_client_socket#2.客户端的ip地址和端口号:ip_port service_client_socket,ip_port=tcp_server_socket.accept()#代码执行到此说明连接建立成

    16、功 print(客户端的ip地址和端口号:,ip_port)#接收客户端发送的数据,这次接收数据的最大字节数是1024 recv_data=service_client_socket.recv(1024)#获取数据的长度 recv_data_length=len(recv_data)print(接收数据的长度为:,recv_data_length)#对二进制数据进行解码 recv_content=recv_data.decode(gbk)print(接收客户端的数据为:,recv_content)TCP编程3 创建TCP服务器端程序创建TCP服务端套接字,设置端口号为8989,设置监听,准备接

    17、受客户端发来的数据,并显示客户端的IP和端口号,演示TCP 服务端程序。#准备发送的数据 send_data=ok,问题正在处理中.encode(gbk)#发送数据给客户端 service_client_socket.send(send_data)#关闭服务与客户端的套接字,终止和客户端通信的服务 service_client_socket.close()#关闭服务端的套接字,终止和客户端提供建立连接请求的服务 tcp_server_socket.close()运行结果:客户端的ip地址和端口号:(192.168.1.102,53524)接收数据的长度为:18接收客户端的数据为:爱你在口,口难

    18、开!网络编程基础网络编程基础 TCP编程编程 多线程编程多线程编程目录这里说明图片内容 多线程编程多任务是指在同一时间内执行多个任务,例如:现在电脑安装的操作系统都是多任务操作系统,可以同时运行着多个软件。有2种执行方式:在一段时间内交替去执行任务。例如:对于单核CPU处理多任务,操作系统轮流让各个软件交替执行,假如:软件1执行0.01秒,切换到软件2,软件2执行并发 对于多核CPU处理多任务,操作系统会给CPU的每个内核安排一个执行的软件,多个内核分别运行不同的程序。并行在Python程序中,想要实现多任务可以使用进程来完成,进程是实现多任务的一种方式。多线程编程1 进程与多进程的使用1.什

    19、么是进程?一个正在运行的程序或者软件就是一个进程一个正在运行的程序或者软件就是一个进程2.多进程的使用PythonPython的多进程包的多进程包multiprocessingmultiprocessing可以完成从单进程到并发执行的转可以完成从单进程到并发执行的转换换,支持子进程、通信和共享数据、执行不同形式的同步,提供了支持子进程、通信和共享数据、执行不同形式的同步,提供了ProcessProcess、LockLock等组件。等组件。ProcessProcess类类,该类可用来在,该类可用来在WindowsWindows平台上创建新进程。使用平台上创建新进程。使用ProcessProces

    20、s类类创建多进程也有以下创建多进程也有以下2 2种方式:种方式:1.1.直接创建直接创建ProcessProcess类的实例对象,由此就可以创建一个新的进程;类的实例对象,由此就可以创建一个新的进程;2.2.通过继承通过继承ProcessProcess类的子类,创建实例对象,也可以创建新的进程。类的子类,创建实例对象,也可以创建新的进程。注意,继承注意,继承ProcessProcess类的子类需重写父类的类的子类需重写父类的run()run()方法。方法。多线程编程1 进程与多进程的使用Process类创建进程(1)导入进程包(2)Process进程类的说明使用 Process 类创建实例化对

    21、象,其本质是调用该类的构造方法创建新进程。import multiprocessing多线程编程1 进程与多进程的使用Process 类的构造方法格式如下:Process(group,target,name,args,kwargs)group:指定进程组 target:执行的目标任务名,为新建进程指定执行任务,也就是指定一个函数 name:为新建进程设置名称 args:以元组方式给执行任务传参 kwargs:以字典方式给执行任务传参多线程编程1 进程与多进程的使用2)Python Process类常用属性和方法多线程编程1 进程与多进程的使用3.获取进程编号获取进程编号的目的是验证主进程和子进

    22、程的关系,可以得知子进程是由那个主进程创建出来的。Process(group,target,name,args,kwargs)group:指定进程组 target:执行的目标任务名,为新建进程指定执行任务,也就是指定一个函数 name:为新建进程设置名称 args:以元组方式给执行任务传参 kwargs:以字典方式给执行任务传参多线程编程1 进程与多进程的使用【例】多进程完成多任务的示例。#1.导入进程包import multiprocessingimport time#跳舞任务def dance():for i in range(3):print(跳舞中.)time.sleep(0.2)#唱

    23、歌任务def sing():for i in range(3):print(唱歌中.)time.sleep(0.2)#2.创建子进程(自己手动创建的进程称为子进程,在_init_.py文件中已经导入的Process类)#group:进程组,目前只能使用None,一般不需要设置#target:进程执行的目标任务#name:进程名,如果不设置,默认是Process-1,.if _name_=_main_:multiprocessing.freeze_support()dance_process=multiprocessing.Process(target=dance)sing_process=mu

    24、ltiprocessing.Process(target=sing)#3.启动进程执行对应的任务dance_process.start()sing_process.start()该例子中,进程执行是无序的,具体哪个进程先执行是由操作系统调度决定。多线程编程1 进程与多进程的使用3.获取进程编号获取进程编号的目的是验证主进程和子进程的关系,可以得知子进程是由那个主进程创建出来的。获取进程编号的两种操作:获取当前进程编号和获取当前父进程编号。获取当前进程编号函数:os.getpid()def dance():#获取当前进程的编号 print(dance:,os.getpid()#获取当前进程 pr

    25、int(dance:,multiprocessing.current_process()for i in range(5):print(跳舞中.)time.sleep(0.2)#扩展:根据进程编号杀死指定进程 os.kill(os.getpid(),9)多线程编程1 进程与多进程的使用4.进程执行带有参数的任务ProcessProcess类执行任务并给任务传参数有两种方式类执行任务并给任务传参数有两种方式:(1)args 表示以元组的方式给执行任务传参(2)kwargs 表示以字典方式给执行任务传参#args:以元组的方式给任务传入参数 sub_process=multiprocessing.

    26、Process(target=task,args=(5,)#kwargs:表示以字典方式传入参数 sub_process=multiprocessing.Process(target=task,kwargs=count:4)多线程编程2 线程与多线程的使用在Python中,线程是实现多任务的另外一种方式。1.什么是线程?线程是进程中执行代码的一个分支,是线程是进程中执行代码的一个分支,是CPUCPU调度的基本单位,每个进程调度的基本单位,每个进程至少都有一个线程至少都有一个线程。2.多线程的使用Python3 线程模块为threading,多线程的使用步骤如下:(1)导入线程模块import

    27、threading多线程编程2 线程与多线程的使用(2)线程类Thread参数说明thread(group,target,name,args,kwargs)group:线程组,目前只能使用None target:执行的目标任务名 args:以元组的方式给执行任务传参 kwargs:以字典方式给执行任务传参 name:线程名,一般不用设置(3)启动线程:通常用start方法。多线程编程2 线程与多线程的使用【例】通过多线程完成唱歌和跳舞两个任务。import threadingimport time#唱歌任务def sing():#扩展:获取当前线程#print(sing当前执行的线程为:,th

    28、reading.current_thread()for i in range(3):print(正在唱歌.%d%i)time.sleep(1)#跳舞任务def dance():#扩展:获取当前线程#print(dance当前执行的线程为:,threading.current_thread()for i in range(3):print(正在跳舞.%d%i)time.sleep(1)多线程编程2 线程与多线程的使用【例】通过多线程完成唱歌和跳舞两个任务。if _name_=_main_:#扩展:获取当前线程#print(当前执行的线程为:,threading.current_thread()#

    29、创建唱歌的线程#target:线程执行的函数名 sing_thread=threading.Thread(target=sing)#创建跳舞的线程 dance_thread=threading.Thread(target=dance)#开启线程 sing_thread.start()dance_thread.start()运行结果:正在唱歌.0正在跳舞.0正在唱歌.1正在跳舞.1正在唱歌.2正在跳舞.2多线程编程2 线程与多线程的使用3.线程执行带有参数的任务ThreadThread类执行任务并给任务传参数有两种方式类执行任务并给任务传参数有两种方式:(1)args 表示以元组的方式给执行任务

    30、传参(2)kwargs 表示以字典方式给执行任务传参#args:以元组的方式给任务传入参数 sub_thread=threading.Thread(target=task,args=(4,)#kwargs:表示以字典方式传入参数 sub_thread=threading.Thread(target=task,kwargs=count:4)多线程编程2 线程与多线程的使用3.线程执行带有参数的任务ThreadThread类执行任务并给任务传参数有两种方式类执行任务并给任务传参数有两种方式:(1)args 表示以元组的方式给执行任务传参(2)kwargs 表示以字典方式给执行任务传参#args:以

    31、元组的方式给任务传入参数 sub_thread=threading.Thread(target=task,args=(4,)#kwargs:表示以字典方式传入参数 sub_thread=threading.Thread(target=task,kwargs=count:4)多线程编程2 线程与多线程的使用在使用线程时,要特别注意如下4点:(1)线程执行执行是无序的(2)主线程默认会等待所有子线程执行结束再结束,设置守护主线程的目的是主线程退出子线程销毁。(3)线程之间共享全局变量,好处是可以对全局变量的数据进行共享。(4)线程之间共享全局变量可能会导致数据出现错误问题,可以使用线程同步方式来解

    32、决这个问题。多线程编程3 互斥锁与死锁1.互斥锁互斥锁是指对共享数据进行锁定,保证同一时刻只能有一个线程去操作。互斥锁是指对共享数据进行锁定,保证同一时刻只能有一个线程去操作。threadingthreading模块中定义了模块中定义了LockLock变量,这个变量本质上是一个函数,通过调变量,这个变量本质上是一个函数,通过调用这个函数可以获取一把互斥锁。用这个函数可以获取一把互斥锁。#创建锁mutex=threading.Lock()#上锁mutex.acquire()#释放锁mutex.release()注意点:acquire和release方法之间的代码同一时刻只能有一个线程去操作多线程

    33、编程3 互斥锁与死锁【例】使用互斥锁完成2个线程对同一个全局变量各加10万次的操作。import threading#定义全局变量g_num=0#创建全局互斥锁lock=threading.Lock()#循环一次给全局变量加1def sum_num1():#上锁 lock.acquire()for i in range(100000):global g_num g_num+=1 print(sum1:,g_num)#释放锁 lock.release()#循环一次给全局变量加1def sum_num2():#上锁 lock.acquire()for i in range(100000):glob

    34、al g_num g_num+=1 print(sum2:,g_num)#释放锁 lock.release()if _name_=_main_:#创建两个线程 first_thread=threading.Thread(target=sum_num1)second_thread=threading.Thread(target=sum_num2)#启动线程 first_thread.start()second_thread.start()运行结果:sum1:100000sum2:200000通过执行结果可以地址互斥锁能够保证多个线程访问共享数据不会出现数据错误问题。多线程编程3 互斥锁与死锁2.

    35、死锁死锁是指一直等待对方释放锁的情景。死锁是指一直等待对方释放锁的情景。死锁的结果是会造成应用程序的停止响应,不能再处理其它任务了。死锁的结果是会造成应用程序的停止响应,不能再处理其它任务了。3.避免死锁避免死锁的方式:在合适的地方释放锁。避免死锁的方式:在合适的地方释放锁。多线程编程4 进程与线程的比较从关系、区别以及优缺点3个方面进行比较:1.从关系角度比较:线程是依附在进程里面的,没有进程就没有线程。线程是依附在进程里面的,没有进程就没有线程。一个进程默认提供一条线程,进程可以创建多个线程。一个进程默认提供一条线程,进程可以创建多个线程。2.从区别角度比较:进程之间不共享全局变量。进程之

    36、间不共享全局变量。线程之间共享全局变量,但是要注意资源竞争的问题,解决办法线程之间共享全局变量,但是要注意资源竞争的问题,解决办法:互互斥锁或者线程同步。斥锁或者线程同步。创建进程的资源开销要比创建线程的资源开销要大。创建进程的资源开销要比创建线程的资源开销要大。进程是操作系统资源分配的基本单位,线程是进程是操作系统资源分配的基本单位,线程是CPUCPU调度的基本单位。调度的基本单位。线程不能够独立执行,必须依存在进程中。线程不能够独立执行,必须依存在进程中。多进程开发比单进程多线程开发稳定性要强。多进程开发比单进程多线程开发稳定性要强。多线程编程4 进程与线程的比较从关系、区别以及优缺点3个

    37、方面进行比较:3.从优缺点角度对比优点:可以用多核缺点:资源开销大进程优点:资源开销小缺点:不能使用多核线程本章小结本章先讲解了网络编程的基础知识,如协议、端口、IP地址和socket网络编程接口等。然后介绍了用Python编写TCP网络程序的步骤。接下来介绍了多线程的概念,并讲解了多进程、线程创建和多线程同步的实现步骤。思考与练习1简述IP地址和网络端口的作用。2简述创建TCP客户端和服务端开发流程,编写一个客户端与服务器端通信程序。3实现一个多线程的TCP服务器,可以同时处理多个客户端连接。4编写Python程序,使用_thread模块中的相应API创建并运行两个线程,使用同一个线程函数,然后在线程函数中使用for循环输出当前线程的名字和循环索引变量值。5使用线程锁将第4题的线程函数加锁,让每一个for循环执行完,再运行另外一个线程函数。

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:Python程序设计课件第12章网络编程和多线程编程.pptx
    链接地址:https://www.163wenku.com/p-3713703.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库