一、socketserver实现并发
基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环。
socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题)
server类:
request类:
继承关系:
以下述代码为例,分析socketserver源码:
ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FtpServer)
ftpserver.serve_forever()
查找属性的顺序:ThreadingTCPServer->ThreadingMixIn->TCPServer->BaseServer
实例化得到ftpserver,先找类ThreadingTCPServer的__init__,在TCPServer中找到,进而执行server_bind,server_active
找ftpserver下的serve_forever,在BaseServer中找到,进而执行self._handle_request_noblock(),该方法同样是在BaseServer中
执行self._handle_request_noblock()进而执行request, client_address = self.get_request()(就是TCPServer中的self.socket.accept()),然后执行self.process_request(request, client_address)
在ThreadingMixIn中找到process_request,开启多线程应对并发,进而执行process_request_thread,执行self.finish_request(request, client_address)
上述四部分完成了链接循环,本部分开始进入处理通讯部分,在BaseServer中找到finish_request,触发我们自己定义的类的实例化,去找__init__方法,而我们自己定义的类没有该方法,则去它的父类也就是BaseRequestHandler中找....
源码分析总结:
基于tcp的socketserver我们自己定义的类中的
self.server即套接字对象
self.request即一个链接
self.client_address即客户端地址
基于udp的socketserver我们自己定义的类中的
self.request是一个元组(第一个元素是客户端发来的数据,第二部分是服务端的udp套接字对象),如(b'adsf', )
self.client_address即客户端地址
importsocketserverimportstructimportjsonimportosclassFtpServer(socketserver.BaseRequestHandler):
coding='utf-8'server_dir='file_upload'max_packet_size=1024BASE_DIR=os.path.dirname(os.path.abspath(__file__))defhandle(self):print(self.request)whileTrue:
data=self.request.recv(4)
data_len=struct.unpack('i',data)[0]
head_json=self.request.recv(data_len).decode(self.coding)
head_dic=json.loads(head_json)#print(head_dic)
cmd=head_dic['cmd']ifhasattr(self,cmd):
func=getattr(self,cmd)
func(head_dic)defput(self,args):
file_path=os.path.normpath(os.path.join(
self.BASE_DIR,
self.server_dir,
args['filename']
))
filesize= args['filesize']
recv_size=0print('----->', file_path)
with open(file_path,'wb') as f:while recv_size
recv_data=self.request.recv(self.max_packet_size)
f.write(recv_data)
recv_size+=len(recv_data)print('recvsize:%s filesize:%s' %(recv_size, filesize))
ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FtpServer)
ftpserver.serve_forever()
FtpServer
importsocketimportstructimportjsonimportosclassMYTCPClient:
address_family=socket.AF_INET
socket_type=socket.SOCK_STREAM
allow_reuse_address=False
max_packet_size= 8192coding='utf-8'request_queue_size= 5
def __init__(self, server_address, connect=True):
self.server_address=server_address
self.socket=socket.socket(self.address_family,
self.socket_type)ifconnect:try:
self.client_connect()except:
self.client_close()raise
defclient_connect(self):
self.socket.connect(self.server_address)defclient_close(self):
self.socket.close()defrun(self):whileTrue:
inp=input(">>:").strip()if not inp:continuel=inp.split()
cmd=l[0]ifhasattr(self,cmd):
func=getattr(self,cmd)
func(l)defput(self,args):
cmd=args[0]
filename=args[1]if notos.path.isfile(filename):print('file:%s is not exists' %filename)return
else:
filesize=os.path.getsize(filename)
head_dic={'cmd':cmd,'filename':os.path.basename(filename),'filesize':filesize}print(head_dic)
head_json=json.dumps(head_dic)
head_json_bytes=bytes(head_json,encoding=self.coding)
head_struct=struct.pack('i',len(head_json_bytes))
self.socket.send(head_struct)
self.socket.send(head_json_bytes)
send_size=0
with open(filename,'rb') as f:for line inf:
self.socket.send(line)
send_size+=len(line)print(send_size)else:print('upload successful')
client=MYTCPClient(('127.0.0.1',8080))
client.run()
FtpClient
二、数据库简介
1、数据库
数据库(database,DB)是指长期存储在计算机内的,有组织,可共享的数据的集合。数据库中的数据按一定的数学模型组织、描述和存储,具有较小的冗余,较高的数据独立性和易扩展性,并可为各种用户共享。
2、数据库管理系统软件
数据库管理系统(Database Management System)是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,简称DBMS。它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。用户通过DBMS访问数据库中的数据,数据库管理员也通过dbms进行数据库的维护工作。它可使多个应用程序和用户用不同的方法在同时或不同时刻去建立,修改和询问数据库。大部分DBMS提供数据定义语言DDL(Data Definition Language)和数据操作语言DML(Data Manipulation Language),供用户定义数据库的模式结构与权限约束,实现对数据的追加、删除等操作。
数据库管理系统是数据库系统的核心,是管理数据库的软件。数据库管理系统就是实现把用户意义下抽象的逻辑数据处理,转换成为计算机中具体的物理数据处理的软件。有了数据库管理系统,用户就可以在抽象意义下处理数据,而不必顾及这些数据在计算机中的布局和物理位置。
常见的数据库管理软件:甲骨文的oracle,IBM的db2,sql server, Access,Mysql(开源,免费,跨平台).
3、数据库系统
数据库系统DBS(Data Base System,简称DBS)通常由软件、数据库和数据管理员组成。其软件主要包括操作系统、各种宿主语言、实用程序以及数据库管理系统。数据库由数据库管理系统统一管理,数据的插入、修改和检索均要通过数据库管理系统进行。数据管理员负责创建、监控和维护整个数据库,使数据能被任何有权使用的人有效使用。
三、MySQL
1、mysql的管理
安装
linux:
--yum -y install mariadb mariadb-server
OR
--yum -y install mysql mysql-server
win:
--http://dev.mysql.com/downloads/mysql/
启动
--service mysqld start #开启
--chkconfig mysqld on #设置开机自启
OR
--systemctl start mariadb
--systemctl enable mariadb
查看
-- ps aux |grep mysqld #查看进程
-- netstat -an |grep 3306 #查看端口
设置密码
-- mysqladmin -uroot password '123' #设置初始密码,初始密码为空因此-p选项没有用
-- mysqladmin -u root -p123 password '1234' #修改root用户密码
登录
-- mysql #本地登录,默认用户root,空密码,用户为root@127.0.0.1
-- mysql -uroot -p1234 #本地登录,指定用户名和密码,用户为root@127.0.0.1
-- mysql -uroot -p1234 -h 192.168.31.95 #远程登录,用户为root@192.168.31.95
mysql的常用命令
-- --启动mysql服务与停止mysql服务命令:-- --net start mysql--net stop mysql-- -- --登陆与退出命令:-- --mysql -h 服务器IP -P 端口号 -u 用户名 -p 密码 --prompt 命令提示符 --delimiter 指定分隔符--mysql -h 127.0.0.1 -P 3306 -uroot -p123--quit------exit----\q;-- -- --\s; ------my.ini文件:[mysql] default-character-set=gbk [mysqld] character-set-server=gbk-- --prompt 命令提示符(\D:当前日期 \d:当前数据库 \u:当前用户)-- --\T(开始日志) \t(结束日志)-- --show warnings;-- --help() ? \h-- --\G;-- --select now();--select version();--select user;-- --\c 取消命令-- --delimiter 指定分隔符
忘记密码怎么办?
方法1:启动mysql时,跳过授权表
[root@controller ~]# service mysqld stop[root@controller ~]# mysqld_safe --skip-grant-table &
[root@controller ~]# mysql
mysql> select user,host,password from mysql.user;+----------+-----------------------+-------------------------------------------+
| user | host | password |
+----------+-----------------------+-------------------------------------------+
| root | localhost | *A4B6157319038724E3560894F7F932C8886EBFCF |
| root | localhost.localdomain | |
| root | 127.0.0.1 | |
| root | ::1 | |
| | localhost | |
| | localhost.localdomain | |
| root | % | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
+----------+-----------------------+-------------------------------------------+
mysql> update mysql.user set password=password("123") where user="root" and host="localhost";
mysql> flush privileges;
mysql> exit
[root@controller ~]# service mysqld restart[root@controller ~]# mysql -uroot -p123
方法2(删库):
删除与权限相关的库mysql,所有的授权信息都丢失,主要用于测试数据库或者刚刚建库不久没有授权数据的情况(从删库到跑路)[root@controller ~]# rm -rf /var/lib/mysql/mysql[root@controller ~]# service mysqld restart[root@controller ~]# mysql
2、sql语句
sql是Structured Query Language(结构化查询语言)的缩写。SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言。
在使用它时,只需要发出“做什么”的命令,“怎么做”是不用使用者考虑的。SQL功能强大、简单易学、使用方便,已经成为了数据库操作的基础,并且现在几乎所有的数据库均支持sql。
2.1sql规范
<1> 在数据库系统中,SQL语句不区分大小写(建议用大写) 。但字符串常量区分大小写。建议命令大写,表名库名小写;
<2> SQL语句可单行或多行书写,以“;”结尾。关键词不能跨多行或简写。
<3> 用空格和缩进来提高语句的可读性。子句通常位于独立行,便于编辑,提高可读性。
SELECT * FROMtb_tableWHERE NAME="YUAN";
<4> 注释:单行注释:--
多行注释:/*......*/
<5>sql语句可以折行操作
<6> DDL,DML和DCL
----SQL中 DML、DDL、DCL区别 .
---- DML(data manipulation language):--它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的--数据进行操作的语言-- ---- DDL(data definition language):--DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)--的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用-- ---- DCL(Data Control Language):--是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)--语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权--力执行DCL
View Code
2.2关于数据库操作的sql语句
--1.创建数据库(在磁盘上创建一个对应的文件夹)
create database [if not exists] db_name [character set xxx]
--2.查看数据库
show databases;查看所有数据库
showcreate database db_name; 查看数据库的创建方式--3.修改数据库
alter database db_name [character set xxx]
--4.删除数据库
drop database [if exists] db_name;--5.使用数据库
切换数据库 use db_name; --注意:进入到某个数据库后没办法再退回之前状态,但可以通过use进行切换
查看当前使用的数据库 select database();
2.3数据表的增删改查
创建一张表
--语法
create tabletab_name(
field1 type[完整性约束条件],
field2 type,
...
fieldn type
)[character set xxx];
--创建一个员工表employee
create tableemployee(
idint primary keyauto_increment ,
namevarchar(20),
genderbit default 1, --gender char(1) default 1 ----- 或者 TINYINT(1)
birthday date,
jobvarchar(20),
salarydouble(4,2) unsigned,
resumetext --注意,这里作为最后一个字段不加逗号
);/*约束:
primary key (非空且唯一) :能够唯一区分出当前记录的字段称为主键!
unique
not null
auto_increment :用于主键字段,主键字段必须是数字类型*/
查看表信息
desctab_name 查看表结构
show columnsfromtab_name 查看表结构
show tables 查看当前数据库中的所有的表
showcreate table tab_name 查看当前数据库表建表语句
修改表结构
--(1)增加列(字段)
alter table tab_name add [column]列名 类型[完整性约束条件][first|after 字段名];alter table user add addr varchar(20) not null unique first/after username;
#添加多个字段alter tableusers2add addr varchar(20),add age intfirst,add birth varchar(20) after name;--(2)修改一列类型
alter table tab_name modify 列名 类型 [完整性约束条件][first|after 字段名];alter table users2 modify age tinyint default 20;alter table users2 modify age intafter id;--(3)修改列名
alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名];alter table users2 change age Age int default 28first;--(4)删除一列
alter table tab_name drop [column]列名;--思考:删除多列呢?删一个填一个呢?
alter tableusers2add salary float(6,2) unsigned not nullafter name,dropaddr;--(5)修改表名
rename table 表名 to新表名;--(6)修该表所用的字符集
alter table student character set utf8;
删除表
drop table tab_name;