11-IO多路复用-paramiko-MySQL
Posted 汉克书
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11-IO多路复用-paramiko-MySQL相关的知识,希望对你有一定的参考价值。
1. IO多路复用
2. paramiko
3. mysql
- SQL语句
- Python操作MySQL - pymysql模块
今日内容:
1. IO多路复用
- 监听多个socket变化
- socket服务端
IO多路复用 + socket 来实现Web服务器
a. 服务端优先运行
b. 浏览器: http://......
socket + send(\'协议..\')
c. 获取客户端发来的url,根据URL不同响应数据
d. 断开链接
产出:
a. 浏览器发送数据:按照指定规则
b. 监听多个socket对象
c.
Web框架开发者
业务开发者
d. 模块独立化
#!/usr/bin/env python # _*_ coding:utf-8 _*_ import select import socket sock = socket.socket() sock.setblocking(False) sock.bind((\'127.0.0.1\',8888)) sock.listen(5) def process_data(client): data = bytes() while True: try: chunk = client.recv(1024) except Exception as e: chunk = None if not chunk: break data += chunk data_str = str(data,encoding=\'utf-8\') header,body = data_str.split(\'\\r\\n\\r\\n\', 1) header_list = header.split(\'\\r\\n\') header_dick = {} for line in header_list: value = line.split(":",1) if len(value) == 2: k,v = value header_dick[k] = v else: header_dick[\'method\'],header_dick[\'url\'],header_dick[\'protocal\'] = line.split(\' \') return header_dick,body inputs = [sock,] while True: rlist,wlist,elist = select.select(inputs,[],[],0.05) for client in rlist: if client == sock: conn,addr = client.accept() conn.setblocking(False) inputs.append(conn) else: header_dicy,body = process_data(client) print(header_dicy) request_url = header_dicy[\'url\'] client.sendall(request_url.encode(\'utf-8\')) inputs.remove(client) client.close()
import select import socket class Http_server(object): def __init__(self,routers): self.routers = routers def process_data(self,conn): data = bytes() while True: try: chunk = conn.recv(1024) except Exception as e: chunk = None if not chunk: break data = data + chunk data_str = str(data, encoding=\'utf-8\') header, body = data_str.split(\'\\r\\n\\r\\n\', 1) header_list = header.split(\'\\r\\n\') header_dict = {} for line in header_list: value = line.split(\':\', 1) if len(value) == 2: k, v = value header_dict[k] = v else: header_dict[\'method\'], header_dict[\'url\'], header_dict[\'protcol\'] = line.split(\' \') return header_dict, body def run(self,host=\'127.0.0.1\',port=8888): sock = socket.socket() # sock.setblocking(False) sock.bind((host,port,)) sock.listen(5) # while True: # conn,addr = sock.accept() # 不在hang主,直接报错 # conn.setblocking(False) # conn.recv(100) # 不在hang主,直接报错 inputs = [sock,] while True: # [1,] rList,wList,eList = select.select(inputs,[],[],0.5) for client in rList: # 建立连接 if client == sock: conn,addr = client.accept() # conn.setblocking(False) inputs.append(conn) else: header_dict,body = self.process_data(client) # client.recv(1024) request_url = header_dict[\'url\'] # routers = [ # (\'/index.html\', f1), # (\'/login.html\', f2) # ] func_name = None for item in self.routers: if item[0] == request_url: func_name = item[1] break if not func_name: client.sendall(b\'404\') else: result = func_name(header_dict,body) client.sendall(result.encode(\'utf-8\')) inputs.remove(client) client.close()
import Http def f1(header_dict,body): # ... Http... # ..... return \'ffffff\' def f2(header_dict,body): return \'aaaaaaaaaa\' routers = [ (\'/index.html\',f1), (\'/login.html\',f2) ] obj = Http.Http_server(routers) obj.run()
参考博客:http://www.cnblogs.com/wupeiqi/p/6536518.html
- socket客户端(爬虫)
利用一个线程,同时发送n个请求(异步非阻塞模块)
url_list [
http://www.baidu.com,
http://www.baidu1.com,
http://www.baidu2.com,
http://www.baidu3.com,
]
import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") application = tornado.web.Application([ (r"/index.html", MainHandler), ]) if __name__ == "__main__": application.listen(8889) tornado.ioloop.IOLoop.instance().start()
a. 循环列表,为每一个URL生成Socket对象
b. 每一个socket对象,向远程发送链接请求
connect: 阻塞
c. 如果连接:
发送数据:遵循格式
d. 获取响应内容
e. 关闭
注意:可读和可写状态
import tornado.ioloop import tornado.web import socket import select sock = socket.socket() sock.fileno() class Foo(object): def __init__(self,sock,callback,url,host): self.sock = sock self.callback = callback self.url = url self.host = host def fileno(self): return self.sock.fileno() class NbIO(object): def __init__(self): self.fds = [] self.connections = [] def connect(self,url_list): for item in url_list: conn = socket.socket() conn.setblocking(False) # 1. 发送链接请求 try: conn.connect((item[\'host\'],80)) except BlockingIOError as e: pass obj = Foo(conn,item[\'callback\'],item[\'url\'],item[\'host\']) self.fds.append(obj) self.connections.append(obj) def send(self): while True: # wList,有对象;当前socket已经创建链接 try: if len(self.fds) == 0: return rList,wList,eList = select.select(self.fds,self.connections,[],0.5) # 【1,11】 for obj in rList: # 4.有数据响应回来了 conn = obj.sock data = bytes() while True: try: d = conn.recv(1024) data = data + d except BlockingIOError as e: d = None if not d: break # print(data) obj.callback(data) # 自定义操作 f1 f2 self.fds.remove(obj) # print(len(self.fds),len(self.connections)) # 执行当前请求 函数:f1 f2 # 【1,2,3,】 for obj in wList: # 2.已经连接上远程 conn = obj.sock # 3. 发送数据 # HTTP/1.0\\r\\nHost: %s\\r\\n\\r\\n template = "GET %s HTTP/1.1\\r\\nHost: %s\\r\\n\\r\\n" %(obj.url,obj.host,) # template = "POST %s HTTP/1.1\\r\\nHost: 127.0.0.1:8888\\r\\n\\r\\nk1=v1&k2=v2" %(obj.url,) conn.sendall(template.encode(\'utf-8\')) self.connections.remove(obj) except OSError as e: pass # 因为win下的select里的列表空了之后会报错,报错就忽视它 class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") application = tornado.web.Application([ (r"/index.html", MainHandler), ]) if __name__ == "__main__": application.listen(8889) tornado.ioloop.IOLoop.instance().start()
参考博客:http://www.cnblogs.com/wupeiqi/articles/6229292.html
产出:
1. setblockint(False)
2. select监听其他对象: def fileno():...
3. gevent,twisted,asycio ---> 单线程并发发送Http请求
2. Paramiko
参考博客:http://www.cnblogs.com/wupeiqi/articles/5095821.html
- 是一个模块,socket,SSH
- Python代码,实现远程服务器操作
功能:
a. 使用用户名密码:
- 命令 SSHClient -> Transport
- 文件 Transport
b. 使用用户名秘钥:
- 命令 SSHClient -> Transport
- 路径,也支持字符串形式
- 文件 Transport
====> SSH帮助类 <====
c.
执行创建session # 堡垒机 Bug
import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname=\'192.168.12.59\', port=22, username=\'root\', password=\'sungaohui1990\') # 执行命令 stdin, stdout, stderr = ssh.exec_command(\'ls /\') # 获取命令结果 result = stdout.read() print(result) # 关闭连接 ssh.close()
import paramiko class SshHelper(object): def __init__(self,host,port,username,pwd): self.host = host self.port = port self.username = username self.pwd = pwd self.transport = None def connect(self): transport = paramiko.Transport((self.host, self.port,)) transport.connect(username=self.username, password=self.pwd) self.transport = transport def upload(self,local,target): sftp = paramiko.SFTPClient.from_transport(self.transport) # 将location.py 上传至服务器 /tmp/test.py sftp.put(local, target) # 将remove_path 下载到本地 local_path # sftp.get(\'remove_path\', \'local_path\') def cmd(self,shell): ssh = paramiko.SSHClient() ssh._transport = self.transport stdin, stdout, stderr = ssh.exec_command(shell) stdout.read() def close(self): self.transport.close() if __name__ == \'__main__\': obj = SshHelper(\'10.0.0.61\',\'22\',\'root\',\'123456\') obj.connect() obj.close()
产出:
- 链接远程,操作:命令,文件
3. MySQL
- 什么是MySQL
服务端:
a.socket服务端运行,监听:IP和端口
b.获取客户端发送的数据:
c.解析
d.去文件中做操作
客户端:
a.socket客户端:基于各种语言的客户端
b.验证
c.发送命令(学习规则SQL语句)
- 安装
服务端:
客户端:
- 基本使用:
a. 申请
用户:
授权:
用户名,数据库(文件夹),表(文件),增删改查,IP
b. 连接
mysql -u root -h c1.com -p asdfasdf mysql -u wupeiqi -h 192.168.12.111 -p 123
c. 规则
文件夹(数据库):
create database db1 default charset utf8; drop database db1; show databases; use db1;
文件(表):
show tables; create table tb1( id int not null auto_increment primary key, name char(20) null default 1, age int not null)engine=innodb default charset utf8; # 增 insert into tb1(name,age) values(\'alex\',18); # 删 delete from tb1 where id>1; # 改 update tb1 set age=168 where id=2; # 查 select * from tb1;
============================================================
外键:foreign key 一对多
create table deparment( id int not null auto_increment primary key, title char(32) null ) create table person( id int not null auto_increment primary key, username char(32) null , age int not null, deparment_id int not null, constraint fk_cc foreign key (deparment_id) references deparment(id) )
双向的外键: 多对多
create table deparment( id int not null auto_increment primary key, title char(32) null ) create table host( id int not null auto_increment primary key, ip char(32) null, port char(32) null ) create table de_2_host( id int not null auto_increment primary key, did int not null, hid int not null, constraint fk_did_deparment foreign key (did) references deparment(id), constraint fk_hid_host foreign key (hid) references host(id) )
连表:
select * from person; select * from person left join deparment on person.deparment_id = deparment.id # 1 alex 18 1 1 咨询 2 oldboy 68 3 3 基础 select id from deparment where title = "基础" select hostid from host_deparment where deparment_id=1111 select * from host id in (1,2,3) #######
4. pymysql
pip3 install pymysql
# 内部socket
import pymysql conn = pymysql.connect(host=\'127.0.0.1\', port=3306, user=\'root\', passwd=\'\', db=\'host_manage\') # cursor = conn.cursor() cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 执行SQL,并返回受影响行数# 被搞... effect_row = cursor.execute("select * from user",) conn.commit() ret = cursor.fetchall() # ret = cursor.fetchmany(3) # ret = cursor.fetchone() # print(ret) # ret = cursor.fetchone() # print(ret) cursor.close() conn.close() print(ret)
import pymysql # 创建连接 conn = pymysql.connect(host=\'127.0.0.1\', port=3306, user=\'root\', passwd=\'123\', db=\'t1\') # 创建游标 cursor = conn.cursor() username = input(\'请输入用户名:\') pwd = input(\'请输入密码:\') # 执行SQL,并返回受影响行数 #effect_row = cursor.execute("select * from userinfo where username=%s and pwd = %s", (username,pwd,)) # root or 1==1 -- # adfasdf # sql = "select * from userinfo where username=%s and pwd = %s" %(username,pwd,) # select * from userinfo where username=root or 1==1 -- and pwd = %s #effect_row = cursor.execute(sql) # 提交,不然无法保存新建或者修改的数据 conn.commit() # 关闭游标 cursor.close() # 关闭连接 conn.close()
以上是关于11-IO多路复用-paramiko-MySQL的主要内容,如果未能解决你的问题,请参考以下文章