您的位置:首页 > 编程语言 > Python开发

6.Socket传文件,多线程开发,paramiko模块

2016-08-24 17:29 225 查看
<--目录-->
1、Socket传文件
2、多线程
3、paramiko

1、Socket传文件
Socket服务端
cat server.py
#!/usr/bin/env python
#coding:utf-8
import SocketServer
import os
class MyServer(SocketServer.BaseRequestHandler):
def handle(self):
base_path = 'g:/index'        #存放接收文件的路径,index文件夹必须事先存在
conn = self.request#收到客户端的请求连接
print 'connected...'#输出连接,代表客户端已跟我建立连接
while True:#死循环
pre_data = conn.recv(1024)#每次接收数据1024,收到客户端发送的请求方法、文件名、文件大小的数据
cmd,file_name,file_size = pre_data.split('|')       #获取请求方法、文件名、文件大小
recv_size = 0                                       #已经接收文件的大小,先定义为0
file_dir = os.path.join(base_path,file_name)        #上传文件路径拼接,即我本地的文件夹路径拼客户端的文件名
f = file(file_dir,'wb')                             #对上传的文件有可写权限
Flag = True
while Flag:                                         #死循环
if int(file_size)>recv_size:#未上传完毕,即客户端传过来给我的文件大小大于我接收到的文件大小
data = conn.recv(1024)#最多接收1024,可能接收的小于1024,接收数据
recv_size+=len(data)                        #将接收的数据加入recv_size
else:#上传完毕,则退出循环
recv_size = 0再次将recv_size定义为0,进行下一次文件的传送接收
Flag = False#定义Flag为False则不再则行死循环
continue#跳出本次循环
f.write(data)#将接收到的数据写入文件
print 'upload successed.'#输出上传成功
f.close()`#关闭文件
instance = SocketServer.ThreadingTCPServer(('127.0.0.1',9999),MyServer)   #异步多线程
instance.serve_forever()


Socket客户端
cat client.py
#!/usr/bin/env python
#coding:utf-8
import socket
import sys
import os
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port)
while True:
input = raw_input('path:')                           #输入路径
cmd,path = input.split('|')                          #前面上传命令,随便写,|后面是本地文件路径 如put|g:/test.txt
file_name = os.path.basename(path)                   #获取文件名字,如test.txt
file_size=os.stat(path).st_size                      #获取文件大小
sk.send(cmd+"|"+file_name+'|'+str(file_size))        #发送 "上传命令" | "文件名" | "文件大小"
send_size = 0                                        #定义发送大小刚开始等于0
f= file(path,'rb')                                   #打开文件
Flag = True
while Flag:                                          #死循环
if send_size + 1024 >file_size:                  #如果发送大小再加+1024则行下面语句,每次发送只能是1024
data = f.read(file_size-send_size)           #总文件大小减去-已发送大小=还没发送大小
Flag = False
else:  #否则
data = f.read(1024) #读文件1024的数据,然后赋值给data
send_size+=1024 #然后发送了的大小每次累加1024
sk.send(data) #发送读的1024的数据
f.close()         #关闭文件
sk.close() #关闭socket


2、多线程开发
start 线程准备就绪,等待CPU调度
setName 为线程设置名称
getName 获取线程名称
setDaemon 设置为后台线程或前台线程(默认)
如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
join 逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
run 线程被cpu调度后自动执行线程对象的run方法

- thred_demo 包
-index.py 模块文件

1)创建线程,执行线程,守护模式
cat index.py
#!/usr/bin/env python
#coding:utf-8
from threading import  Thread
import time
def Foo(arg,v):
for item in range(100):
print item
time.sleep(1)
print  'before'
t1 = Thread(target=Foo,args=('abc',1,))  #与函数建立关系,创建线程
t1.setDaemon(True)     #守护模式,只执行主线程,如果主线程一直没有结束,子线程会执行,什么时候主线程结束了,子线程才会跟着一起销毁
t1.start()             #执行线程
print
#print  t1.isDaemon    #子线程执行完了,主线程才中断,这个很少用
print  t1.getName()    #输出线程名字
print  'after'
print  'after'
print  'after'
print  'after end'
time.sleep(3)


2)join练习
#!/usr/bin/env python
#coding:utf-8
from threading import  Thread
import time
def Foo(arg,v):
for item in range(100):
print item
time.sleep(1)
print  'before'
t1 = Thread(target=Foo,args=('abc',1,))  #与函数建立关系
#t1.setDaemon(True)  #守护模式,只执行主线程,主线程执行结束了,子线程也会跟着销毁
t1.start()             #执行线程
t1.join(5)    #只执行到Join这里,下面的内容主线程不再执行,只执行子线程的,最多给你五秒时间,超时则执行下面主线程的内容
print
print  t1.getName()    #输出线程名字
print  'after'
print  'after'
print  'after'
print  'after end'
time.sleep(10)


3)自定义线程类,run()练习示例
from threading import Thread
import time
class MyThread(Thread):  #继承Thread
def run(self):
#time.sleep(10)
print '我是线程'
Thread.run(self)   #调用父类的run方法 ,如果没有这句,则不会执行下面函数的print 'bar'
def Bar():
print 'bar'
t1 = MyThread(target=Bar)
t1.start()
print  'over'


4)面向对象实现生产者消费者模型
cat producter_demo.py
#!/usr/bin/env python
#coding:utf-8
from threading import Thread
from Queue import  Queue
import time
class Procuder(Thread):
def __init__(self,name,queue):
'''
@param name:生产者的名称
@param queue:容器
'''
self.__Name = name
self.__Queue = queue
super(Procuder,self).__init__() #调用父类的构造函数
def run(self):
while True:
if self.__Queue.full():    #包子满了
time.sleep(1)
else:
self.__Queue.put('baozi')
time.sleep(1)
print '%s 生产了一个包子' %(self.__Name,)
#Thread.run(self)
class Consumer(Thread):
def __init__(self,name,queue):
'''
@param name:生产者的名称
@param queue:容器
'''
self.__Name = name
self.__Queue = queue
super(Consumer,self).__init__()   #调用父类的构造函数
def run(self):
while True:
if self.__Queue.empty():  #没有包子了则休息一秒
time.sleep(1)
else:
self.__Queue.get('baozi')
time.sleep(1)
print '%s 消费了一个包子' %(self.__Name,)
#Thread.run(self)
que = Queue(maxsize=100)  #创建一个队列,空间大小一百,放包子
baogou1 = Procuder('老王1',que)
baogou1.start()
baogou2 = Procuder('老王2',que)
baogou2.start()
baogou3 = Procuder('老王3',que)
baogou3.start()
for item in range(20):
name = 'chentao%d' %(item,)
temp = Consumer(name,que)
temp.start()
'''
print que.qsize()    #查看占用的数据大小为0
que.put('1')  #往里面存放数据
que.put('2')  #往里面存放数据
print 'empty:',que.empty()  #查看是为空,不为空就是有数据也就是False
print que.qsize()   #查看占用的数据大小为2
print 'get:',que.get()  #取数据1
print 'get:',que.get()  #取数据2,取到没有了就不会再取了
print 'empty:',que.empty()   #为空没数据为就是True
'''


5)函数式编程实现生产者消费者模型
cat consumer_producer.py
#!/usr/bin/env python
#coding:utf-8
import threading
import time
import Queue
import random
def Proudcer(name,que):
while True:
if que.qsize() < 3:
que.put('baozi')
print '%s:生产一个包子==========================='  %name    #生产一个包子
time.sleep(random.randrange(4))        #随机睡眠N秒后再生产包子
else:
print U'还有大于或等于3个包子'
def Consumer(name,que):
while True:
try:
que.get_nowait()                       #取得一个包子,默认先生产的就先取得,如果没有包子,就会报错
except Exception:
print U'没有包子了。。。'
else:
print '%s:买一个包子'    %name
time.sleep(random.randrange(3))            #随机睡眠N秒后再买包子
q = Queue.Queue()     #定义容器,没定义大小就是无限大
p1 = threading.Thread(target=Proudcer,args=['zhang1',q])
p2 = threading.Thread(target=Proudcer,args=['zhang2',q])
p1.start()
p2.start()
c1 = threading.Thread(target=Consumer,args=['xie1',q])
c2 = threading.Thread(target=Consumer,args=['xie2',q])
c1.start()
c2.start()


进程和线程的区别?
1、进程可以理解为一个应用程序在处理机上的一次执行过程,一个进程包含多个线程
2、进程间相互独立,同一进程的各线程间共享内存,某线程内的线程在其它进程不可见
3、进程不可以共享内存,进程产生子进程,并且子进程继承了对应的父进程的大部分属性

多线程开发之线程锁( threading.Lock() ),一把锁
#!/usr/bin/env python
#coding:utf-8
import threading
import time
num = 0
def run(n):
time.sleep(1)
global num         #加上global可以在局部变量改全局变量的值
lock.acquire()     #加上锁,单线程执行
num +=1
lock.release()     #解锁,加锁了就要解锁
print '%s\n' %num

lock = threading.Lock()
for i in range(100):
t = threading.Thread(target=run,args=(i,))
t.start()


#多把锁实战( threading.RLock() )
#!/usr/bin/env python
#coding:utf-8
import threading
import time
num = 0
num2 = 0
def run(n):
time.sleep(1)
global num         #加上global可以在局部变量改全局变量的值
global num2
lock.acquire()     #加上锁,单线程执行
num += 1
lock.acquire()
num2 += 2
lock.release()
lock.release()     #解锁,加锁了就要解锁
time.sleep(0.01)
print '%s\n' %num
lock = threading.RLock()
for i in range(200):
t = threading.Thread(target=run,args=(i,))
t.start()


设置允许最大连接数、线程数
#!/usr/bin/env python
#coding:utf-8
import threading
import time
num = 0
def run(n):
time.sleep(1)
global num         #加上global可以在局部变量改全局变量的值
samp.acquire()     #加上锁,4线程同时执行
num += 1
print '%s' %num
samp.release()     #解锁
samp = threading.BoundedSemaphore(4)  #最大连接数,也就是同时运行的线程数
for i in range(200):
t = threading.Thread(target=run,args=(i,))
t.start()


多线程开发之事件(通过信号来做数据交互)
#!/usr/bin/env python
#coding:utf-8
import threading
import time
def producer():
print  u'老蔡:等人来买包子。。。'
event.wait()           #等待对方的事件
event.clear()          #清空事件,把True变为False
print u"老蔡:你是要来买包子吗"
print u"老蔡:包子就快做好了"
time.sleep(5)
print u'老蔡:你的包子做好了'
event.set()            #设置事件,变为True
def consumer():
print u'老王:去买包子。。。'
event.set()             #用来设置事件告知对方
time.sleep(2)
print u"老王:等你的包子做好呀"
while True:
if event.isSet():   #用来检测事件变量是否设置,该函数返回的是否布尔值,即true/false
print u"老王:Thanks..."
break
else:
print u"还没做好吗"
time.sleep(1)
event = threading.Event()
p = threading.Thread(target=producer)
c = threading.Thread(target=consumer)
p.start()
c.start()


paramiko详解(第三方模块需要下载)
下载安装
pycrypto-2.6.1.tar.gz
paramiko-1.10.1.tar.gz
yum install gcc python-devel

1、下载安装 pycrypto-2.6.1.tar.gz
解压,进入,python setup.py build【编译】,python setup.py install 【安装】 ----》import Crypto

2、下载安装 paramiko-1.10.1.tar.gz  
解压,进入,python setup.py build【编译】,python setup.py install 【安装】---》 import paramiko

#基于密码连接
[root@test1 opt]# cat ssh.py
#!/usr/bin/env python
#coding:utf-8
import paramiko

# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机,平常连接会要你输入YES,有了这句话直接允许不用输入YES
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.200.11', port=22, username='root', password='hengtai')

# 执行命令,stdin是输入命令,stdout是输出的结果,stderr是指输出的报错,三个都要写上去,否则执行会报错
stdin,stdout,stderr = ssh.exec_command('df -h')
# 获取命令结果
result_out = stdout.read()
result_err = stderr.read()
print result_out
print result_err

# 关闭连接
ssh.close()


#基于密钥连接
[root@test1 opt]# cat skey.py
#!/usr/bin/env python
#coding:utf-8
import paramiko
private_key_path = '/root/.ssh/id_rsa'    #输入Key的路径
key = paramiko.RSAKey.from_private_key_file(private_key_path)   #获得key
ssh = paramiko.SSHClient()   #获取连接ssh方法
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())   #获允许连接不在know_hosts文件中的主机
ssh.connect(hostname='192.168.200.11', port=22, username='root', pkey=key)  #连接相关信息
stdin, stdout, stderr = ssh.exec_command('ifconfig')  #执行命令
print stdout.read()   #输出命令
ssh.close();   #关闭
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  开发 Python