Fork me on GitHub

Python学习笔记之网络编程

操作MySQL

# 断言 assert(1==1)

#############################################################################

********************************************************************
# 创建Connection                                                   *        
-------------------------------------------------------------------*
Connection:创建了Python客户端与数据库之间的网络通路。他的参数如下 *
-------------------------------------------------------------------*
参数名        类型        说明                                       *
host        String        MySQL的服务器地址                           *
port        int            MySQL的端口号                               *
user        String        用户名                                       *
passwd        String        密码                                       *
db            String        使用的数据库                               *
charset        String        连接字符集                                   *
                                                                 *    
-------------------------------------------------------------------*
Connection支持的方法:                                               *
-------------------------------------------------------------------*
方法名        说明                                                   *
cursor()    创建并且返回游标                                       *
commit()    提交当前事物                                           *
rollback()    回滚当前事物r()                                        *
close()        关闭Connection                                         *
-------------------------------------------------------------------*
#获取Cursor.                                                       *
-------------------------------------------------------------------*
Cursor:游标对象,用于执行查询和获取结果,它支持的方法如下:        *
-------------------------------------------------------------------*
方法名                说明                                           *
execute()            用于执行一个数据库的查询命令                   * 
fetchone()            获取结果集中的下一行                           *
fetchmany(size)     获取结果集中的下(size)行                     *
fetchall()            获取结果集中剩下的所有行                       *
rowcount            最近一次execute返回数据/影响的行数             *
close()                关闭游标                                       * 
********************************************************************

#############################################################################
创建连接:conn = pymysqsl.connect(xxxx)
创建游标:cur = conn.cursor()
执行sql:cur.execute(sql)
返回所有结果:data = cur.fetchall()
返回N行结果: cur.fetchmany(3)
返回一行结果:cur.fetchone
关闭游标,数据库
cur.close()
conn.close()

#############################################################################
# 该模块防sql注入, 不支持+字符串链接,默认%s占位符
sql =  "insert into admin(name,address) values (%s,%s)"
params = ('alex_1', 'usea')
recout =  cur.execute(sql, params)
# insert、update、del的时候需要commit,select的时候不需要
con.commit

# commit 提交

#在fetch数据时按照顺序进行,可以使用cursor.scroll(num,mode)来移动游标位置,如:

    cursor.scroll(1,mode='relative')  # 相对当前位置移动
    cursor.scroll(2,mode='absolute') # 相对绝对位置移动
#############################################################################
# 多条
sql =  "insert into admin(name,address) values (%s,%s)"
params = [
            ('alex_1', 'usea'),
            ('alex_2', 'usea')
        ]
recout =  cur.executemany(sql, params)

#执行多条sql,只会提交一次,失败则回滚
con.commit  

# 显示sql列名, 游标 设置为字典类型
cur = con.cursor(cursor = pymysql.cursors.DictCursor)

# 获取自增id
cur.lastrowid
#############################################################################
# 事务
    事物用于将某些操作的多个sql作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性
    
# 事务的特性
    事务有以下四个标准属性的缩写ACID,通常被称为:
        1.原子性:确保工作单元内的所有操作都成功完成,否则事务将被中止在故障点,和以前的操作将回滚到以前的状态
        2.一致性:确保数据库正确地改变状态后,成功提交事务
        3.隔离性:使事务操作彼此独立和透明的
        4.持久性:确保提交的事务的结果或交过的系统出现故障的情况下仍然存在
    
    在MySQL中,事务开始使用commit或rollback语句开始工作和结束。开始和结束语句的sql命令之间形成大量的事务。
#COMMIT % ROLLBACK
    这俩个关键字提交和回滚主要用于MySQL的事务。
    
    当一个成功的事务完成后,发出commit命令应使所有参与表的更改才会生效
    
    如果发生故障时,应发出一个rollback命令返回的事务中引用的每一个表以前的状态
    
    可控制的事务行为成为AUTOCOMMIT设置会员变量。如果AUTOCOMMIT设置为1(默认值),人后每一个sql语句(在事务与否)被认为是一个完整的事务,并承诺在默认情况下,当它完成。
    AUTOCOMMIT设置为0时,发出SET AUTOCOMMIT = 0 命令,在随后的一系列语句的作用就像一个事务,知道一个明确的COMMIT语句时,没有活动的提交
    
    可以通过使用mysql_query()函数在php中执行这些sql命令
    
# 通用事务例子
    这一系列事件是独立于所使用的编程语言,可以建立在任何使用的语言来创建应用程序的逻辑路径
    可以通过使用mysql_query()函数在php中执行这些sql命令
    
    BEGIN WORK开始事务发出sql命令
    
    发出一个或多个sql命令,如select、insert、update、delete
    检查是否有任何错误,一切都依据的需要
    如果有任何错误,那么问题rollback命令,否则发出commit命令
    
# 在项目设计里面,牵扯到金钱的转义,于是就要用到mysql的事务处理,来确保一组处理结果的正确性。用了事务,就不可避免的要牺牲一部分速度,来确保数据的正确性
    事务ACID Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
    1.事务的原子性
        一组事务,要么成功,要么撤回
    2.稳定性
        有非法数据(外键约束之类),事务撤回
    3.隔离性
        事务独立运行
            一个事务处理后的结果,影响了其他事务,那么其他事务会撤回
            事务的100%隔离,需要牺牲速度
    4.可靠性
        软、硬件奔溃后,InnoDB数据表驱动会利用日志文件重构修改
        可靠性和高速度不可兼得,innodb_flush_log_at_trx_commit选项,决定什么时候把事务保存到日志里
        
        开启事务
            START TRANSACTION 或 BEGIN
        
        提交事务(关闭事务)
            COMMIT
            
        放弃事务(关闭事务)
            ROLLBACK
            
        折返点
            SAVEPOINT adqoo_1
            ROLLBACK TO SAVEPOINT adqoo_1
            发生在折返点adqoo_1之前的事务被提交,之后的被忽略
            
        事务的终止
            设置"自动提交" 模式
            SET AUTOCOMMIT = 0
            每条SQL都是同一个事务的不同命令,之间有COMMIT 或 ROLLBACK隔开
            掉线后,没有COMMIT的事务都被放弃
            
# 事务锁定模式
    系统默认:不需要等待某事务结束,可直接查询到结果,但不能再进行修改、删除
    缺点:查询到的结果,可能是已经过期的
    优点:不需要等待某事务结束,可直接查询到结果
    
# 需要用以下模式来设定锁定模式
    1.SELECT....LOCK IN SHARE MODE(共享锁)
        查询到的数据,就是数据库在这一时刻的数据(其他已COMMIT事务的结果,已经反应到这里了)
        SELECT 必须等待,某个事务结束后才能执行
    
    2.SELECT...FOR UPDATE(排它锁)
        例如 SELECT* FROM tablename WHERE id < 200
        那么当id < 200的数据,被查询到的数据,都将不能再进行修改、删除、SELECT...LOCK IN SHARE MODE 操作  一直到事务结束
        
        共享锁和排它锁的区别:在于是否阻断其他用户发出的SELECT...LOCK IN SHARE MODE 命令
        
    3.INSERT/UPDATE/DELETE
        所有关联数据都会被锁定,加上排它锁
        
    4.防插入锁
        例如SELECT * FROM tablename WHERE id > 200
        那么id  > 200的记录无法被插入
        
    5.死锁
        自动识别死锁
        先进来的进程被执行,后来的进程收到出错的消息,并按ROLLBACK方式回滚
        innodb_lock_wait_timeout = n 来设置最长等待时间、默认50秒
                
# 事务隔离模式
    
    SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL
    READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
    
    1.不带SESSION/GLOBAL的SET命令
        只对下一个事务有效
    
    2.SET SESSION|
        为当前会话设置隔离模式
        
    3.SET GLOBAL
        为以后新建的所有MYSQL连接设置隔离模式(当前了解不包括在内)
        
# 隔离模式
    READ UNCOMMITTED
    
    不隔离SELECT
        其他事务未完成的修改(未COMMIT),其结果也在考虑之内
        
    READ COMMITTED
        把其他事务的 COMMIT 修改考虑在内
        同一个事务中,同一 SELECT 可能返回不同结果
    
    EPEATABLE READ(默认)
        不把其他事务的修改考虑在内,无论其他事务是否用COMMIT命令提交过
        同一个事务中,同一 SELECT 返回同一结果(前提是本事务,不修改)

   SERIALIZABLE
        和REPEATABLE READ类似,给所有的SELECT都加上了 共享锁

    出错处理
        根据出错信息,执行相应的处理
        
# MYSQL的事务处理主要有两种方法
    1.用begin,rollback,commit 来实现
        begin开始一个事务
        rollback事务回滚
        commit事务确认
        
    2.直接用set来改变mysql的自动提交模式
        mysql默认是自动提交的,也就是你提交一个query,就直接指向!可以通过
        set autocommit = 0 禁止自动提交
        set autocommit = 1 开启自动提交
      来实现事务的处理
    
    但要注意当用set autocommit = 0 的时候,你以后所有的sql都将作为事务处理,直到你用commit确认或 rollback结束,注意当你结束这个事务的同时也开启了新的事务!按第一种方法只将当前的做为一个事务!
    MYSQL只有 INNODB和BDB类型的数据表才支持事务处理,其他的类型是不支持的!
            
    

 

 

Socket

 

# 三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:
    表现层(Presentation layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。
        1、表现层(UI):通俗讲就是展现给用户的界面,即用户在使用一个系统的时候他的所见所得。
        2、业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。
        3、数据访问层(DAL):该层所做事务直接操作数据库,针对数据的增添、删除、修改、查找等。
        
########################################################################################################################    
TCP/IP不是一个协议,而是一个协议族的统称。里面包括IP协议、IMCP协议、TCP协议。

TCP/IP分层:应用层HTTP/FTP,传输层TCP/UDP,网络层ip协议 ARP/RARP , 数据链路层

# 协议
*********************************************************
7 应用层     |                <应用层>                    *
--------------         TELNET,SSH,HTTP,SMIP,POP,          *
6 表示层     |         SSL/TLS,FTP,MIME,HTML,           *
--------------           SNMP,MIB,SIP,RTP....           *
5 会话层     |                                          * 
--------------------------------------------------------*
4 传输层     |                <传输层>                    *
             |        TCP,UDP,UDP-Lite,SCTP,DCCP        *
--------------------------------------------------------*
3 网络层     |                <网络层>                    *
             |          ARP,IPv4,IPv6,ICMP,IPsec        *
--------------------------------------------------------*
2 数据链路层 |                                          *
--------------          以太网,无线WLAN、PPP.........    *
1 物理层     |          (双纹线电缆,无线,光纤...)     *
*********************************************************

########################################################################################################################
        
# socket
    Python提供两个级别访问的网络服务
        1.低级别的网络服务支持基本的socket,他提供了标准的BSD sockets API, 可以访问底层操作系统Socket接口的全部方法
        2.高级别的网络服务模块SocketServer,它提供了服务器中心类,可以简化网络服务器的开发

# 什么是socket
    socket又称"套接字", 应用程序通常通过"套接字"向网络发出请求或者应答网请求,使主机间或者一台计算机上的进程可以通讯
    
    socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也
    称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。
    在Internet上的主机一 般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。



########################################################################################################################
# TCP服务器                                              *           # TCP客户端    
1  通过socket类创建socket对象 socket()                  *        4  通过socket类创建socket对象 socket()
2  socket绑定ip,端口 bind()                          *        5  connect()连接服务,指定主机和端口
3  listen()最大的连接数,监听                          *           7  客户端链接成功,想服务器发送链接状态信息
6  通过阻塞的accept()方法获得客户端返回的链接信息     *           9  客户端向socket写入信息(或服务端向socket写入信息)
8  服务器accept方法返回,连接成功                      *        11 客户端关闭
10 服务器读取信息(客户端读取信息)
12 服务器端关闭


########################################################################################################################
# 连接原理
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接 字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。


########################################################################################################################
服务器端

s.bind()     
# 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
s.listen()     
# 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
s.accept()     
# 被动接受TCP客户端连接,(阻塞式)等待连接的到来


客户端

s.connect()     
# 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex()     
# connect()函数的扩展版本,出错时返回出错码,而不是抛出异常


公共用途的函数

s.recv()     
# 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
s.send()     
# 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall()     
# 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
s.close()
# 关闭套接字


s.recvform()     
# 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
s.sendto()     
# 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
s.getpeername()     
# 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
s.getsockname()     
# 返回套接字自己的地址。通常是一个元组(ipaddr,port)
s.setsockopt(level,optname,value)     
# 设置给定套接字选项的值。
s.getsockopt(level,optname[.buflen])      
# 返回套接字选项的值。
s.settimeout(timeout)     
# 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
s.gettimeout()     
# 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
s.fileno()     
# 返回套接字的文件描述符。
s.setblocking(flag)     
# 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
s.makefile()     
# 创建一个与该套接字相关连的文件


########################################################################################################################
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
参数一:地址簇
    socket.AF_INET IPv4(默认)
    socket.AF_INET6 IPv6
    socket.AF_UNIX 只能够用于单一的Unix系统进程间通信
参数二:类型
    socket.SOCK_STREAM  流式socket , for TCP (默认)
    socket.SOCK_DGRAM   数据报式socket , for UDP
    socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而
    SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以
    通过IP_HDRINCL套接字选项由用户构造IP头。
    socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。
    SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,
    如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
  socket.SOCK_SEQPACKET 可靠的连续数据包服务
参数三:协议
    0  (默认)与特定的地址家族相关的协议,如果是 0 ,
    则系统就会根据地址格式和套接类别,自动选择一个合适的协议

recv 从缓存区拿数据,最多只能拿1024字节

########################################################################################################################

#!/usr/bin/evn python3
# _*_ coding:utf-8 _*_
import socket


# #############客户端####################


# 第一步创建一个socket对象
client = socket.socket()


# 第二步连接服务
ip_port = ('127.0.0.1', 8080)
client.connect(ip_port)


while True:
# 第三步 获取数据
data = client.recv(1024)
print(data.decode('utf-8'))
# 发送数据
inp = input('clent:')
client.send(inp.encode("utf-8"))
if inp == 'exit':
break

 

 

#!/usr/bin/evn python3
# _*_ coding:utf-8 _*_
import socket

# #############服务端####################

# 第一步创建一个socket对象
sk = socket.socket()

# 第二步绑定ip、端口
ip_port = ('127.0.0.1', 8080)
sk.bind(ip_port)

# 第四步 设置监听
sk.listen(5)

while True:
# 第五步 接收请求,获取到客户端的socket对象和ip端口
conn, address = sk.accept()
# 第六步,给客户端发信息
conn.send('hello'.encode('utf-8'))
# 第七步,close
flag = True
while flag:
data = conn.recv(1024)
print(data)
if data == 'exit':
flag = False
conn.send('pm 是个煞笔'.encode('utf-8'))
conn.close()

 

 

#!/usr/bin/evn python3
# _*_ coding:utf-8 _*_
import socketserver


# #############多线程服务端####################


class MyServer(socketserver.BaseRequestHandler):

def handle(self):
conn = self.request
conn.sendall('hello'.encode('utf-8'))
flag = True
while flag:
data = conn.recv(1024)
if data == 'exit':
flag = False
conn.send('pm 是个煞笔'.encode('utf-8'))
conn.close()

if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyServer)
server.serve_forever()



 

posted @ 2017-12-29 10:27  未凉残念浮生若梦  阅读(233)  评论(0编辑  收藏  举报