day08
异常处理
报错格式及顺序
try:print("try报错 就匹配执行except类型,没有则报错,Exception指定所有报错")except Exception as e:print(e)else:print("如果try没报错,执行else")finally:print("无论执行try或else 最后都执行finally")
简单实例
#输入1或0try:s = 1if s is 0:#print("%s 是错误的"%s)raise NameError("%s 是错误的"%s) #如果引发NameError异常,后面的代码将不能执行print(len(s))except TypeError:print("%s 是错误的" % s)
实例
#捕获出错后,提示异常信息,且不退出,捕获错误可多个#Exception捕获所有错误,写其他错误类型就是捕获具体错误类型,写一种类型加一个except#输入字符串 提示报错并继续while True:num1 = input("请输入第一位数字:")num2 = input("请输入第二位数字:")try:num1 = int(num1)num2 = int(num2)result = num1 + num2exit("%s + %s = %s"%(num1,num1,result))except NameError as e:#捕获具体错误,后操作如下,报错重要性可写入log,也可忽略,print("出现异常,信息如下:")print(e)except Exception as e:#捕获所有错误print("出现异常,信息如下:")print(e)#invalid literal for int() with base 10: 'asfd' 这是说第10行输入不是int类型
主动错误模式
try:raise Exception('错误了。。。')except Exception as e:print(e)#错误了。。。
自定义异常模式
class guolm(Exception): #创建类 传参是Exception(所有报错)def __init__(self,msg):self.message = msgdef __str__(self):return self.messagetry:raise guolm("我的异常") #主动异常except guolm as e:print(e)#我的异常
断言
assert 1 == 1 #条件满足则继续assert 1 == 2 #条件不满足则报错
错误类型
python2.x捕获异常语法:try:...some functions...except Exception, e:print(e)python3.x捕获异常语法:try:...some functions...except Exception as e:print(e)注意这里 Exception, e 变成了 Exception as epython常见的异常类型0.Exception 捕获所有错误1. NameError: 尝试访问一个未申明的变量>>> vNameError: name 'v' is not defined2. ZeroDivisionError: 除数为0>>> v = 1/0ZeroDivisionError: int division or modulo by zero3. SyntaxError: 语法错误int intSyntaxError: invalid syntax (<pyshell#14>, line 1)4. IndexError: 索引超出范围List = [2]>>> List[3]Traceback (most recent call last):File "<pyshell#18>", line 1, in <module>List[3]IndexError: list index out of range5. KeyError: 字典关键字不存在,试图访问字典里不存在的键Dic = {'1':'yes', '2':'no'}>>> Dic['3']Traceback (most recent call last):File "<pyshell#20>", line 1, in <module>Dic['3']KeyError: '3'6. IOError: 输入输出错误:基本上是无法打开文件>>> f = open('abc')IOError: [Errno 2] No such file or directory: 'abc'7. AttributeError: 访问未知对象属性>>> class Worker:def Work():print("I am working")>>> w = Worker()>>> w.aTraceback (most recent call last):File "<pyshell#51>", line 1, in <module>w.aAttributeError: 'Worker' object has no attribute 'a'8.ValueError: 数值错误>>> int('d')Traceback (most recent call last):File "<pyshell#54>", line 1, in <module>int('d')ValueError: invalid literal for int() with base 10: 'd'9. TypeError: 类型错误>>> iStr = '22'>>> iVal = 22>>> obj = iStr + iVal;Traceback (most recent call last):File "<pyshell#68>", line 1, in <module>obj = iStr + iVal;TypeError: Can't convert 'int' object to str implicitly- 10. AssertionError: 断言错误
>>> assert 1 != 1Traceback (most recent call last):File "<pyshell#70>", line 1, in <module>assert 1 != 1AssertionError11. MemoryError: 内存耗尽异常12.ImportError 无法引入模块或包;基本上是路径问题或名称错误
13.IndentationError 语法错误(的子类) ;代码没有正确对齐
14.KeyboardInterrupt Ctrl+C被按下 15.UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量, 导致你以为正在访问它
16. NotImplementedError: 方法没实现引起的异常class Base(object):def __init__(self):passdef action(self):#抛出异常,说明该接口方法未实现raise NotImplementedError- 17. LookupError: 键、值不存在引发的异常
LookupError异常是IndexError、KeyError的基类, 如果你不确定数据类型是字典还是列表时,可以用LookupError捕获此异常18. StandardError 标准异常除StopIteration, GeneratorExit, KeyboardInterrupt 和SystemExit外,其他异常都是StandarError的子类。错误检测与异常处理区别在于:错误检测是在正常的程序流中,处理不可预见问题的代码,例如一个调用操作未能成功结束
更多错误
ArithmeticErrorAssertionErrorAttributeErrorBaseExceptionBufferErrorBytesWarningDeprecationWarningEnvironmentErrorEOFErrorExceptionFloatingPointErrorFutureWarningGeneratorExitImportErrorImportWarningIndentationErrorIndexErrorIOErrorKeyboardInterruptKeyErrorLookupErrorMemoryErrorNameErrorNotImplementedErrorOSErrorOverflowErrorPendingDeprecationWarningReferenceErrorRuntimeErrorRuntimeWarningStandardErrorStopIterationSyntaxErrorSyntaxWarningSystemErrorSystemExitTabErrorTypeErrorUnboundLocalErrorUnicodeDecodeErrorUnicodeEncodeErrorUnicodeErrorUnicodeTranslateErrorUnicodeWarningUserWarningValueErrorWarningZeroDivisionError更多异常
socket
#socket 讲解 http://www.cnblogs.com/alex3714/articles/5227251.html# 武老师 http://www.cnblogs.com/wupeiqi/articles/5040823.htmlimport socketphone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #获取tcp/ip套接字#phone = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #获取udp/ip套接字phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #防止端口结束不释放phone.bind(('127.0.0.1',8010)) #绑定服务端ip+端口phone.listen(5) #监听最大连接数为5phone.setblocking(bool) #是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错phone.accept()#conn,client_addr=phone.accept() #conn是建立连接(具体跟某个用户的连接通信),client_addr是客户端访问的ip+port#接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。#接收TCP 客户的连接(阻塞式)等待连接的到来phone.connect(('127.0.0.1',8080)) #连接server服务的ip+port 连接请求phone.close() #关闭连接phone.recv(1024) #一次接受数据大小sk.recvfrom(bufsize[.flag]) #和recv一样,只是多了从哪里接受的数据地址sk.send(string[,flag]) #发送数据 所有通信(整个手机的通信)sk.sendall(string[,flag]) #发送所有数据sk.sendto(string[,flag],address) #和send功能一样 但需要指定远程地址,一半不用sk.settimeout(timeout) #超时时间 连接远程机器 多长时间超时sk.getpeername() #返回远程地址 返回值通常是元组(ipaddr,port)sk.getsockname() #返回本机地址。通常是一个元组(ipaddr,port)sk.fileno() #套接字的文件描述符socket.sendfile(file, offset=0, count=None) #发送文件 ,但目前多数情况下并无什么卵用
socket实现简单通信
运行方式先启动server在启动client
server端
import socketserver=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #获取tcp/ip套接字 socket.AF_INET家庭模式 socket.SOCK_STREAM通讯方式是tcp#phone = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 获取udp/ip套接字server.bind(("127.0.0.1",8000)) #绑定服务端ip+portserver.listen(5) #最大监听连接数为5conn,client_addr=server.accept() #接受用户连接并返回数据#conn是建立连接(具体跟某个用户的连接通信,当前连接的用户),client_addr是客户端访问的ip+portprint(conn,client_addr)while True:data=conn.recv(1024) #1024是字节 #一次接收数据最大值print("rece",data)conn.send(b"got your msg") #发送数据,conn.send()发送数据给正在连接的conn用户
client端
import socketclient=socket.socket() #固定连接client.connect(("127.0.0.1",8000)) #指定服务端ip+portwhile True: #指定循环发送数据msg= input(">>>").strip()if len(msg)==0:continue #用户输入不为空client.send(msg.encode()) #发送byte类型数据#client.send(b"hello") #python只能发bite数据,encode()默认是byte类型print("send",msg)data=client.recv(1024) #接受单次数据最大值1024字节print("receive from server:",data)
socket实现简单通信 ,多个用户交互连接不中断
server端
import socketserver=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#获取tcp/ip套接字 socket.AF_INET家庭模式 socket.SOCK_STREAM通讯方式是tcp#phone = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)获取udp/ip套接字server.bind(("127.0.0.1",8000)) #绑定服务端ip+portserver.listen(5) #最大监听连接数为5while True: #当前用户断开,下一个用户连接正常接入conn,client_addr=server.accept() #接受用户连接并返回数据#conn是建立连接(具体跟某个用户的连接通信,当前连接的用户),client_addr是客户端访问的ip+portprint(conn,client_addr)while True: #用于用户多次交互try:data=conn.recv(1024) #1024是字节 #一次接收数据最大值print("rece",data)conn.send(b"got your msg") #发送数据,conn.send()发送数据给正在连接的conn用户except Exception: #因为client断开会影响server端 特加异常处理#conn.close() #这个不需要加 会自动释放break
client
看第一次client配置 (这次配置2个用户,)
执行方式 先开启服务器 在开启client端(2个)
粘包
socket 模拟ssh登录
执行方式 先启动server 再启动client
server端
import socketimport subprocessserver=socket.socket(socket.AF_INET,socket.SOCK_STREAM)server.bind(("127.0.0.1",8300)) #绑定服务端ip+portserver.listen(5) #最大监听连接数为5while True: #当前用户断开,下一个用户连接正常接入conn,client_addr=server.accept() #接受用户连接并返回数据print(conn,client_addr)while True: #用于用户多次交互data=conn.recv(1024) #1024是字节 #一次接收数据最大值print("rece",data)res_obj= subprocess.Popen(data, shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE)res= res_obj.stdout.read() #读取成功日志conn.send(str(len(res)).encode()) #len转成str并变成byte格式print("---res len---",len(res),str(len(res)).encode())conn.send(res) #发送数据
client端
import socketclient=socket.socket() #固定连接client.connect(("127.0.0.1",8300)) #指定服务端ip+portwhile True: #指定循环发送数据msg= input(">>>").strip()if len(msg)==0:continue #用户输入不为空client.send(msg.encode()) #发送byte类型数据data=client.recv(1024) #接受单次数据最大值1024字节total_size = int(data.decode())received_size = 0res = b'' #定义byte格式while received_size < total_size: #total_size是server端发送的数据,如果不为执行如下d = client.recv(1024) #每次接受1024,res += dreceived_size += len(d) #received_size == total_size后,说明接受完毕,结束循环print("--------end----------------------------")print(res.decode()) #解密显示数据
服务器端
import socket#获取tcp/ip套接字phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #获取tcp/ip套接字#phone = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 获取udp/ip套接字phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #防止端口结束不释放phone.bind(('127.0.0.1',8010)) #绑定服务端ip+端口phone.listen(5) #最大连接数print('server start...')while True: #链接循环conn,client_addr=phone.accept()print(conn,client_addr)while True: #通讯循环try:client_data=conn.recv(1024) #接受数据if not client_data:break #针对linux系统conn.send(client_data.upper()) #发送数据 #sedall 发送所有数据#except Exception: #针对windwosbreakconn.close() #这是客户端链接断开phone.close() #这是服务端断开#socket.SOCK_STREAM #流式协议,基于tcp协议#socket.SOCK_DGRAM #udp协议 数据报协议#bind内写元祖 ,内学本机ip+port#phone.listen(5) 最大挂起连接数为5#conn.recv(1024) 收发消息 最大接受限制1024#conn 是socket记录信息#<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 60617)>#client_addr 是客户端访问的ip+port,('127.0.0.1', 60617)
client端 可以多个
import socketphone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)phone.connect(('127.0.0.1',8080))while True:msg=input('>>: ').strip()if not msg:continuephone.send(msg.encode('utf-8'))# print('====>has send')server_data=phone.recv(1024)# print('====>has recv')print(server_data.decode('utf-8'))phone.close()

python解决办法
phone=socket(AF_INET,SOCK_STREAM)phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加phone.bind(('127.0.0.1',8080))
linux解决办法
发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,vi /etc/sysctl.conf编辑文件,加入以下内容:net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_fin_timeout = 30然后执行 /sbin/sysctl -p 让参数生效。net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

浙公网安备 33010602011771号