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()    
server
#!/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
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()
View Code

注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。

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
View Code

通过特殊的数据结构,可以完成进程间的数据共享

#方法一,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()
View Code

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)
View Code

 

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();
View Code

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()
View Code

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();
View Code

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()
View Code

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();
View Code

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();
View Code

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
View Code

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
View Code

 

posted @ 2015-03-22 07:04  武沛齐  阅读(8539)  评论(0编辑  收藏  举报