一、异常处理

1)异常处理的使用意义

 什么是异常处理
异常是程序发生错误的信号,即程序一旦出错就会立刻产生一个异常,如果该异常没有被处理
那么异常就抛出来,程序的运行也随之终止 异常分为三部分:
异常的类型
异常的内容、提示信息
异常的追踪/定位信息信息 捕捉/检测异常,一旦发生异常就立刻执行相应的处理逻辑,而不是任由异常抛出来终止程序
为何要进行异常处理
增强程序的健壮性 如何进行异常处理
try...except...

2)逻辑错误导致的异常

# int('xxxxxxx') #ValueError

# age #NameError

# for i in : #TypeError:
# pass # l=[]
# l[] #IndexError # d={'x':}
# d['y'] #KeyError # / #ZeroDivisionError

3)异常处理的单分支结构

try:
l=[,,]
l[]
print('====>')
except IndexError:
print('=====>NameError')
print('其他代码')

4)异常的多分支结构

try:
age
l=[,,]
# l[]
d={'x':}
# d['y']
print('====>')
except NameError as e:
print('NameError: %s' %e)
except IndexError as e:
print('IndexError: %s' %e)
except KeyError as e:
print('KeyError: %s' %e) print('其他代码')

5)万能异常:Exception,可以匹配所有种类的异常,最好不要直接万能匹配异常

try:
# age
l=[,,]
# l[]
d={'x':}
d['y']
print('====>')
except Exception as e:
print(e) print('其他代码')

6)多分支+Exception,注意Exception一定要放到except 其他异常的的后面

try:
d={'x':}
d['y']
print('====>')
except IndexError as e:
print('IndexError: %s' %e)
except KeyError as e:
print('KeyError:%s' %e)
except Exception as e:
print(e) print('其他代码')

7)try...else,else会在被检测的代码块没有异常发生的情况下执行, else一定要与except连用,并且一定要放到多个except后面

try:
l=[,,]
print('====>')
except IndexError as e:
print('IndexError: %s' %e)
except KeyError as e:
print('KeyError:%s' %e)
except Exception as e:
print(e)
else:
print('else的代码只有在被检测的代码块没有异常发生的情况下才会执行')

8)try...finally,finnaly的代码会什么时候运行? finally应放到最后面,常应用于回收资源使用

try:
f=open('a.txt','w')
d={'x':}
print(d['y'])
except KeyError as e:
print('KeyError:%s' %e)
except Exception as e:
print(e)
else:
print('else的代码只有在被检测的代码块没有异常发生的情况下才会执行')
finally:
print('finally的代码,无论被检测的代码有无异常,都会执行,通常在finally内做一些回收资源的事情')
f.close() print('其他代码')

9)主动触发异常raise 异常类型(’异常的内容‘)

print('===>1')
raise TypeError('类型错误')
print('===>2')
# 应用于程序中自定义某种法则,一旦不遵循则会像抛出语法异常一样,终止程序的运行

10)断言,和代替raise触发的异常

info=[,,,,,]

# if len(info) != :
# raise ValueError('值的个数 < 7')
assert len(info) == # 我断定len(info) == ,如果我断言失败,程序则抛出异常 print('阶段2--->1')

11)自定义异常

class MyError(BaseException):
def __init__(self,msg):
super().__init__()
self.msg=msg
def __str__(self):
return '<%s>' %self.msg raise MyError('我自己定义的异常')

二、socker套接字网络编程,tcp连接方式

1)套接字工作流程

先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

2)实例化出简单的服务端和客户端程序

import socket

#、买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #流式协议指的就是tcp协议
# print(phone) #、插手机卡
phone.bind(('127.0.0.1',)) #端口范围0- #、开机
phone.listen() #限制的是请求数,而非链接数 #、等待电话连接
print('服务的启动......')
conn,client_addr=phone.accept() #(tcp的连接对象,客户端的ip和端口)
print(conn)
print(client_addr) #、收消息
data=conn.recv() #最大接收1024bytes
print('客户端数据:%s' %data)
#、发消息
conn.send(data.upper()) #、挂电话
conn.close() #、关机
phone.close()

服务端

import socket

#、买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #流式协议指的就是tcp协议 #、打电话,建电话连接
phone.connect(('127.0.0.1',)) #ip和端口都是服务端的 #、发消息
phone.send('hello world'.encode('utf-8')) #、收消息
data=phone.recv()
print(data) #、挂电话
phone.close()

客户端

3)加上通信循环

import socket

#、买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #流式协议指的就是tcp协议
# print(phone) #、插手机卡
phone.bind(('127.0.0.1',)) #端口范围0- #、开机
phone.listen() #限制的是请求数,而非链接数 #、等待电话连接
print('服务的启动......')
conn,client_addr=phone.accept() #(tcp的连接对象,客户端的ip和端口)
print(conn)
print(client_addr) while True: # 通信循环
try: #针对的是windows系统
#、收消息
data=conn.recv() #最大接收1024bytes
if not data:break #针对的linux系统
print('客户端数据:%s' %data)
#、发消息
conn.send(data.upper())
except ConnectionResetError:
break #、挂电话
conn.close() #、关机
phone.close()

服务端

import socket

#、买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #流式协议指的就是tcp协议 #、打电话,建电话连接
phone.connect(('127.0.0.1',)) #ip和端口都是服务端的 while True:
msg=input('>>>: ').strip()
#、发消息
phone.send(msg.encode('utf-8')) #、收消息
data=phone.recv()
print(data.decode('utf-8')) #、挂电话
phone.close()

客户端

4)加上连接循环,可等待多个连接进来

import socket

#、买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #流式协议指的就是tcp协议
# print(phone)
# phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,) #就是它,在bind前加 #、插手机卡
phone.bind(('127.0.0.1',)) #端口范围0- #、开机
phone.listen() #限制的是请求数,而非链接数 #、等待电话连接
print('服务的启动......') while True: # 连接循环
conn,client_addr=phone.accept() #(tcp的连接对象,客户端的ip和端口)
# print(conn)
print(client_addr) # 通信循环
while True:
try: #针对的是windows系统
#、收消息
data=conn.recv() #最大接收1024bytes
if not data:break #针对的linux系统
print('客户端数据:%s' %data)
#、发消息
conn.send(data.upper())
except ConnectionResetError:
break #、挂电话
conn.close() #、关机
phone.close()

服务端

import socket

#、买手机
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #流式协议指的就是tcp协议 #、打电话,建电话连接
phone.connect(('127.0.0.1',)) #ip和端口都是服务端的 while True:
msg=input('>>>: ').strip() #msg=''
if not msg:continue
#、发消息
phone.send(msg.encode('utf-8'))
print('has send====>') #、收消息
data=phone.recv()
print('has recv====>')
print(data.decode('utf-8')) #、挂电话
phone.close()

客户端

5)模拟ssh远程执行命令

from socket import *
import subprocess phone=socket(AF_INET,SOCK_STREAM)
phone.bind(('127.0.0.1',))
phone.listen() print('服务的启动......')
# 连接循环
while True:
conn,client_addr=phone.accept()
print(client_addr) # 通信循环
while True:
try:
cmd=conn.recv()
if not cmd:break obj=subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) stdout=obj.stdout.read()
stderr=obj.stderr.read() # conn.send(stdout+stderr)
print(len(stdout)+len(stderr))
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
conn.close() phone.close()

服务端

from socket import *

phone=socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',)) while True:
cmd=input('>>>: ').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8')) res=phone.recv() # *
print(res.decode('gbk')) phone.close()

客户端

发现了粘包问题

6)解决粘包问题

from socket import *
import subprocess
import struct phone=socket(AF_INET,SOCK_STREAM)
phone.bind(('127.0.0.1',))
phone.listen() print('服务的启动......')
# 连接循环
while True:
conn,client_addr=phone.accept()
print(client_addr)
# 通信循环
while True:
try:
cmd=conn.recv()
if not cmd:break
obj=subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout=obj.stdout.read()
stderr=obj.stderr.read()
# 、先发送固定长度的报头
#目前报头里只包含数据的大小
total_size=len(stdout) + len(stderr)
conn.send(struct.pack('i',total_size))
# 、发送真实的数据
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
conn.close()
phone.close()

服务端

from socket import *
import struct phone=socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',))
while True:
cmd=input('>>>: ').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8'))
#、先收报头,从报头里取出对真实数据的描述信息
header=phone.recv()
total_size=struct.unpack('i',header)[]
#、循环接收真实的数据,直到收干净为止
recv_size=
res=b''
while recv_size < total_size:
recv_data=phone.recv()
res+=recv_data
recv_size+=len(recv_data)
print(res.decode('gbk'))
phone.close()

客户端

7)解决粘包报头数据过大问题,先转json,再转报头

from socket import *
import subprocess
import struct
import json phone=socket(AF_INET,SOCK_STREAM)
phone.bind(('127.0.0.1',))
phone.listen() print('服务的启动......')
# 连接循环
while True:
conn,client_addr=phone.accept()
print(client_addr) # 通信循环
while True:
try:
cmd=conn.recv()
if not cmd:break
obj=subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) stdout=obj.stdout.read()
stderr=obj.stderr.read() #制作报头
header_dic={
'filename':'a.txt',
'total_size':len(stdout) + len(stderr),
'md5':'xxxxxsadfasdf123234e123'
}
header_json = json.dumps(header_dic)
header_bytes=header_json.encode('utf-8') #、先发送报头的长度
conn.send(struct.pack('i',len(header_bytes))) #、再发送报头
conn.send(header_bytes) #、最后发送真实的数据
conn.send(stdout)
conn.send(stderr) except ConnectionResetError:
break
conn.close() phone.close()

服务端

from socket import *
import struct
import json phone=socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',)) while True:
cmd=input('>>>: ').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8')) #、先收报头的长度
obj=phone.recv()
header_size=struct.unpack('i',obj)[] #、再接收报头
header_bytes=phone.recv(header_size)
header_json=header_bytes.decode('utf-8')
header_dic=json.loads(header_json)
print(header_dic) total_size=header_dic['total_size']
#、循环接收真实的数据,直到收干净为止
recv_size=
res=b''
while recv_size < total_size:
recv_data=phone.recv()
res+=recv_data
recv_size+=len(recv_data) print(res.decode('gbk')) phone.close()

客户端

8) socketserver模块实现并发的套接字通信

基于tcp的并发线程通信

import socketserver

# 通信循环
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
data=self.request.recv()
if not data:break
self.request.send(data.upper())
except ConnectionResetError:
break
self.request.close()
if __name__ == '__main__':
# 连接循环
server=socketserver.ThreadingTCPServer(('127.0.0.1',),MyTCPHandler)
server.serve_forever()

服务端

import socket

client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

client.connect(('127.0.0.1',)) #ip和端口都是服务端的

while True:
msg=input('>>>: ').strip()
client.send(msg.encode('utf-8'))
data=client.recv()
print(data.decode('utf-8')) client.close()

客户端

基于udp的并发线程通信

import socketserver

# 通信循环
class MyUDPHandler(socketserver.BaseRequestHandler):
def handle(self):
# print(self.request)
res=self.request[]
print('客户端发来的数据:',res) self.request[].sendto(res.upper(),self.client_address) if __name__ == '__main__':
#连接循环
server=socketserver.ThreadingUDPServer(('127.0.0.1',),MyUDPHandler)
server.serve_forever()

udpserver

import socket
import os client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) while True:
msg='%s hello' %os.getpid()
client.sendto(msg.encode('utf-8'),('127.0.0.1',)) res,server_addr=client.recvfrom()
print(res)

udpclient

三、socket套接字,基于UDP的连接方式

1)udp的工作模式

from socket import *
import time server=socket(AF_INET,SOCK_DGRAM) # 数据报协议UDP
#、基于udp协议每发送的一条数据都自带边界,即udp协议没有粘包问题
#、基于udp协议的通信,一定是一发对应一收 server.bind(('127.0.0.1',)) while True:
msg,client_addr=server.recvfrom() # 接收客户端的信息
print(msg ,client_addr)
time.sleep()
server.sendto(msg.upper(),client_addr) # 给客户端回消息

服务端

from socket import *

client=socket(AF_INET,SOCK_DGRAM)

while True:
# msg=input('>>: ').strip()
client.sendto('egon'.encode('utf-8'),('127.0.0.1',)) # 给服务端发送消息 res,server_addr=client.recvfrom()
print(res)

客户端

2) udp的连接特点

、一发对应一收
、没有粘包问题
、只能接收数据量比较小的内容,如果接收的byte数量小于了发送的数量,会丢数据
from socket import *

server=socket(AF_INET,SOCK_DGRAM) # 数据报协议UDP
#、基于udp协议每发送的一条数据都自带边界,即udp协议没有粘包问题
#、基于udp协议的通信,一定是一发对应一收 server.bind(('127.0.0.1',)) msg1,client_addr=server.recvfrom()
print(msg1)
msg2,client_addr=server.recvfrom()
print(msg2)
msg3,client_addr=server.recvfrom()
print(msg3)

服务端

from socket import *

client=socket(AF_INET,SOCK_DGRAM)

client.sendto('hello'.encode('utf-8'),('127.0.0.1',))
client.sendto('world'.encode('utf-8'),('127.0.0.1',))
client.sendto('egon'.encode('utf-8'),('127.0.0.1',))

客户端

原文链接:http://www.cnblogs.com/linhaifeng/articles/6129246.html

Python之异常处理和socket套接字连接7的更多相关文章

  1. PHP Socket(套接字连接)扩展简介和使用方法

    PHP socket扩展是基于流行的BSD sockets,实现了和socket通讯功能的底层接口,它可以和客户端一样当做一个socket服务器. 使用这些函数时请注意,虽然他们中有很多和C函数同名的 ...

  2. Python Web学习笔记之socket套接字

    套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象.它们允许程序接受并进行连接,如发送和接受数据.为了建立通信通道,网络通信 ...

  3. Python 31 TCP协议 、socket套接字

    1.TCP协议 可靠传输,TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的长度,以确保单个TCP数据包不必再分割. (1)三次握手建链接( ...

  4. 进击的Python【第七章】:python各种类,反射,异常处理和socket基础

    Python的高级应用(三)面向对象编程进阶 本章学习要点: 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 一.面向对象高级语法部分 静态方法 ...

  5. python之异常处理和re模块补充

    一.re模块的补充 1.从一个字符串中获取要匹配的内容 findall:返回一个列表 2.search ***** 验证用户输入内容 '^正则规则$':返回一个对象,用group()取值 3.matc ...

  6. 19、网络编程 (Socket套接字编程)

    网络模型 *A:网络模型 TCP/IP协议中的四层分别是应用层.传输层.网络层和链路层,每层分别负责不同的通信功能,接下来针对这四层进行详细地讲解. 链路层:链路层是用于定义物理传输通道,通常是对某些 ...

  7. 31_网络编程(Socket套接字编程)_讲义

    今日内容介绍 1.网络三要素及传输协议 2.实现UDP协议的发送端和接收端 3.实现TCP协议的客户端和服务器 4.TCP上传文件案例 01网络模型 *A:网络模型 TCP/IP协议中的四层分别是应用 ...

  8. Python开发基础-Day23try异常处理、socket套接字基础1

    异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解 ...

  9. python基础之try异常处理、socket套接字基础part1

    异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解 ...

随机推荐

  1. Python memoryview() 函数

    Python memoryview() 函数  Python 内置函数 描述 memoryview() 函数返回给定参数的内存查看对象(Momory view). 所谓内存查看对象,是指对支持缓冲区协 ...

  2. linux之docker学习

    1.redis主从同步 可以主从数据同步,从库只读,只能手动切换主备关系2.redis哨兵 -准备redis主从数据库环境 -准备redis哨兵(可以有一个,可以有多个) -哨兵检测redis主库状态 ...

  3. POJ-2251.DungeonMaster(三维BFS)

    做题时需要注意,爬楼有向上和向下爬之分... 本题大意:输入 l, r, c, 分别代表地牢的楼层数和每层地牢的长和宽,地牢由rock and point and source and key组成,你 ...

  4. Bitmap byte[] InputStream Drawable 互转

    import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStrea ...

  5. http://ctf.bugku.com/challenges#%E6%B8%B8%E6%88%8F%E8%BF%87%E5%85%B3--游戏过关

      做成功这道逆向题了,哈哈哈哈.   启程.   运行了一下子程序,发现它是要保证所有灯亮着才会给flag.如下图所示.   我聪明滴认为首先可以通过关键字符串找到关键代码位置哦. 1.找到关键代码 ...

  6. RocketMq顺序消费

    部分内容出处   https://www.jianshu.com/p/453c6e7ff81c rocketmq内部有4个默认的队里,在发送消息时,同一组的消息需要按照顺序,发送到相应的mq中,同一组 ...

  7. angular实现链接锚记

    前言: 之所以这么说,是因为angular的路由将html默认的链接锚记的#给占用了,所以传统的链接锚记在这里将不再适用,这个有点坑啊,又要多写好几行代码来模拟这个功能. 实现原理: location ...

  8. [剑指Offer]25-合并两个排序链表

    题目链接 https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337?tpId=13&tqId=11169&t ...

  9. fastjson的常用方法

    /** * 解析对象形式的json字符串 */ public static void test1() { String jsonStr = "{\"JACKIE_ZHANG\&qu ...

  10. java命令启动jacocoagent及生成报告

    启动jacocoagent: java -Xms1024m -Xmx2048m -XX:-UseGCOverheadLimit -Ddruid.keepAlive=true -javaagent:/h ...