08day06
上节回顾
- 面向对象拾遗
- 断言
- python mysql
- 三层架构
- socket
本节内容
ftp上传
#!/usr/bin/env python #coding:utf-8 import SocketServer import os class MyServer(SocketServer.BaseRequestHandler): def handle(self): base_path = 'G:/temp' conn = self.request print 'connected...' while True: pre_data = conn.recv(1024) #获取请求方法、文件名、文件大小 cmd,file_name,file_size = pre_data.split('|') #已经接收文件的大小 recv_size = 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: #最多接收1024,可能接收的小于1024 data = conn.recv(1024) recv_size+=len(data) #上传完毕,则退出循环 else: recv_size = 0 Flag = False continue #写入文件 f.write(data) print 'upload successed.' f.close() instance = SocketServer.ThreadingTCPServer(('127.0.0.1',9999),MyServer) instance.serve_forever()
#!/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) container = {'key':'','data':''} while True: input = raw_input('path:') cmd,path = input.split('|') file_name = os.path.basename(path) file_size=os.stat(path).st_size sk.send(cmd+"|"+file_name+'|'+str(file_size)) send_size = 0 f= file(path,'rb') Flag = True while Flag: if send_size + 1024 >file_size: data = f.read(file_size-send_size) Flag = False else: data = f.read(1024) send_size+=1024 sk.send(data) f.close() sk.close() client
线程和进程简介
- 应用程序和进程以及线程的关系?
- 一个应用程序里可以有多个进程,一个进程里可以有多个线程 最原始的计算机是如何运行的?
- CPU是什么?为什么要使用多个CPU?
- 为什么要使用多线程?
- 为什么要使用多进程?
- java和C#中的多线程和python多线程的区别?
- python多线程和傻缺的GIL python
- 如何让程序真正的实现同时运行?
- 线程和进程的选择:计算密集型和IO密集型程序。(IO操作不占用CPU)
进程的开销通常比线程昂贵, 因为线程自动共享内存地址空间和文件描述符. 意味着, 创建进程比创建线程会花费更多
在执行一些sleep/read/write/recv/send这些会导致阻塞的函数时,当前线程会主动放弃GIL,然后调用相应的系统API,完成后再重新申请GIL。因此,GIL也并不是导致Python的多线程完全没用,在一些IO等待的场合,Python多线程还是发挥了作用,当然如果多线程都是用于CPU密集的代码,那多线程的执行效率就明显会比单线程的低。
多线程开发
1、threading.Thread模块
- start
- getName()
- setName()
- isDaemon()
- setDaemon()
- join(timeout)
- run()
thread 和 threading 模块的选择?使用更高级的threading模块
2、线程锁
线程锁中的threading.Lock 和 threading.Rlock
#!/usr/bin/env python #coding:utf-8 import threading import time gl_num = 0 lock = threading.RLock() def Func(): lock.acquire() global gl_num gl_num +=1 time.sleep(1) print gl_num lock.release() for i in range(10): t = threading.Thread(target=Func) t.start()
多进程开发
1、创建进程程序
from multiprocessing import Process import threading import time def Foo(i): print 'say hi',i for i in range(10): p = Process(target=Foo,args=(i,)) p.start()
注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。
2、进程间的数据共享
默认各自持有一份
#!/usr/bin/env python #coding:utf-8 from multiprocessing import Process from multiprocessing import Manager import time li = [] def Foo(i): li.append(i) print 'say hi',li for i in range(10): p = Process(target=Foo,args=(i,)) p.start() print li
通过特殊的数据结构,可以完成进程间的数据共享
#方法一,Array from multiprocessing import Process,Array temp = Array('i', [11,22,33,44]) def Foo(i): temp[i] = 100+i for item in temp: print i,'----->',item for i in range(2): p = Process(target=Foo,args=(i,)) p.start() p.join() #方法二:manage.dict()共享数据 from multiprocessing import Process,Manager manage = Manager() dic = manage.dict() def Foo(i): dic[i] = 100+i print dic.values() for i in range(2): p = Process(target=Foo,args=(i,)) p.start() p.join() #方法三:manage.Namespace()共享数据 from multiprocessing import Process,Manager manage = Manager() namespace = manage.Namespace() namespace.x = [11,22,33] def Foo(i,dic): namespace.x = [11,22,33,i] print namespace for i in range(2): p = Process(target=Foo,args=(i,namespace)) p.start() p.join()
3、进程池
from multiprocessing import Process,Pool def Foo(i): #print i return i+100 def Bar(arg): print arg pool = Pool(5) #print pool.apply(Foo,(1,)) #print pool.apply_async(func =Foo, args=(1,)).get() pool.apply_async(func =Foo, args=(1,),callback=Bar)
Paramiko
一、安装,下载
1、下载安装 pycrypto-2.6.1.tar.gz (apt-get install python-dev)
解压,进入,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
二、paramiko 功能
1、连接远程服务器,并执行操作
用户名和密码连接
#!/usr/bin/env python #coding:utf-8 import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('192.168.1.108', 22, 'alex', '123') stdin, stdout, stderr = ssh.exec_command('df') print stdout.read() ssh.close();
2、上传和下载文件
import os,sys import paramiko t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',password='WOshiniba8') sftp = paramiko.SFTPClient.from_transport(t) sftp.put('/tmp/test.py','/tmp/test.py') t.close() import os,sys import paramiko t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',password='WOshiniba8') sftp = paramiko.SFTPClient.from_transport(t) sftp.get('/tmp/test.py','/tmp/test2.py') t.close()
3、通过SSH连接服务器
ssh-keygen -t rsa
ssh-copy-id -i ~/ssh/id_rsa.pub wupeiqi@192.168.159.129
import paramiko private_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(private_key_path) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('182.92.219.96 ', 22, 'wupeiqi', 'xxxx', key) stdin, stdout, stderr = ssh.exec_command('df') print stdout.read() ssh.close();
4、SSH上传和下载文件
import paramiko pravie_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(pravie_key_path) t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',pkey=key) sftp = paramiko.SFTPClient.from_transport(t) sftp.put('/tmp/test3.py','/tmp/test3.py') t.close() import paramiko pravie_key_path = '/home/auto/.ssh/id_rsa' key = paramiko.RSAKey.from_private_key_file(pravie_key_path) t = paramiko.Transport(('182.92.219.86',22)) t.connect(username='wupeiqi',pkey=key) sftp = paramiko.SFTPClient.from_transport(t) sftp.get('/tmp/test3.py','/tmp/test4.py') t.close()
5、第三种连接
import paramiko scp = paramiko.Transport(('182.92.219.86',22)); scp.connect(username='wupeiqi',password='xxx'); channel = scp.open_session(); print channel.exec_command('mkdir hello') channel.close(); scp.close();
6、交互式连接
import paramiko scp = paramiko.Transport(('182.92.219.86',22)); scp.connect(username='wupeiqi',password='xxx'); channel = scp.open_session(); print channel.exec_command('mkdir hello') channel.close(); scp.close(); import paramiko import interactive ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('192.168.1.108', 22, 'alex', '123') channel = ssh.invoke_shell() interactive.interactive_shell(channel) channel.close() ssh.close();
7、paramiko的demo.py文件
审计系统
需求:记录用户在服务器的所有操作!!
1、需要一台主机当作堡垒机
2、所有用户只能登录堡垒机
3、登录堡垒机后,可以对远程服务器进行操作
4、记录用户的所有操作
【登录堡垒机】--> 【选择服务器】 --> 【操作服务器,并记录操作】
实现:
1、创建堡垒机用户
adduser xxx
2、用户登录堡垒机后,自动执行脚本
配置 .brashrc
添加 /usr/bin/python /home/wupeiqi/share/workspace/07day07/section_two/menu.py
3、堡垒机提示与用户对应的服务器
import os,sys msg = """ \033[42;1mWelcome using old boy's auditing system!\033[0m """ print msg host_dic = { 'zhangke': '10.0.0.137', 'xiaoqing': '10.0.0.135', 'hanxin' : '10.0.1.139' } while True: for hostname, ip in host_dic.items(): print hostname,ip try: host = raw_input('Please choose one server to login:').strip() if host == 'quit': print "Goodbye!" break except KeyboardInterrupt:continue except EOFError:continue if len(host) ==0:continue if not host_dic.has_key(host) : print 'No host matched, try again.' continue print '\033[32;1mGoing to connect \033[0m', host_dic[host] os.system("python demo.py %s" % host_dic[host]) menu
4、记录操作日志
# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com> # # This file is part of paramiko. # # Paramiko is free software; you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # # Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Paramiko; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. import socket import sys # windows does not have termios... try: import termios import tty has_termios = True except ImportError: has_termios = False def interactive_shell(chan): if has_termios: posix_shell(chan) else: windows_shell(chan) def posix_shell(chan): import select oldtty = termios.tcgetattr(sys.stdin) try: tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) chan.settimeout(0.0) f = file('/tmp/auto.log','a+') while True: r, w, e = select.select([chan, sys.stdin], [], []) if chan in r: try: x = chan.recv(1024) if len(x) == 0: print '\r\n*** EOF\r\n', break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read(1) f.write(x) f.flush() if len(x) == 0: break chan.send(x) f.close() finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) # thanks to Mike Looijmans for this code def windows_shell(chan): import threading sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n") def writeall(sock): while True: data = sock.recv(256) if not data: sys.stdout.write('\r\n*** EOF ***\r\n\r\n') sys.stdout.flush() break sys.stdout.write(data) sys.stdout.flush() writer = threading.Thread(target=writeall, args=(chan,)) writer.start() try: while True: d = sys.stdin.read(1) if not d: break chan.send(d) except EOFError: # user hit ^Z or F6 pass