上節回顧
- 面向對象拾遺
- 斷言
- 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