一、异常处理

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. 手机端用swiper组件 轮播图设置后右侧出现空白 及 部分手机浏览器打开网页空白

    我的方法是设置内容css overflow:hidden;width:100%; ok. 之前搜到一个方法也可以,就是设置css height: auto;overflow-y: scroll; 但是 ...

  2. ffmpeg编码中的二阻塞一延迟

    1. avformat_find_stream_info接口延迟 不论是减少预读的数据量,还是设置flag不写缓存,我这边都不实用,前者有风险,后者会丢帧,可能我还没找到好姿势,记录在此,参考:htt ...

  3. 58. Length of Last Word (String)

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  4. Delphi异步编程:匿名线程与匿名方法

    异步编程,是项目中非常有用的而且常用的一种方法,大多以线程实现. 而Delphi传统方法使用线程略为烦琐,好在其后续版本中,提供一些方法,简化一些操作. 几个概念: 匿名线程:TAnonymousTh ...

  5. 2017-2018-2 20165315 实验三《敏捷开发与XP实践》实验报告

    2017-2018-2 20165315 实验三<敏捷开发与XP实践>实验报告 一.编码标准 编写代码一个重要的认识是"程序大多时候是给人看的",编程标准使代码更容易阅 ...

  6. GridView(网格视图)+MotionEvent(触控事件)实现可以拖动排序的网格图

    1.一触碰,就回调onInterceptTouchEvent(MotionEvent ev)事件,每次的触碰都只回调一次,接着只要还没有放手,就一直回调onTouchEvent(MotionEvent ...

  7. 35-BigDecimal详解

    详解 import java.math.BigDecimal; import java.math.BigInteger; import java.util.Scanner; public class ...

  8. Task.WaitAll代替WaitHandle.WaitAll

    Task.Waitall阻塞了当前线程直到全完.whenall开启个新监控线程去判读括号里的所有线程执行情况并立即返回,等都完成了就退出监控线程并返回监控数据. task.Result会等待异步方法返 ...

  9. mysql 存储过程 与 循环

    mysql 操作同样有循环语句操作,三种标准循环模式:while, loop,repeat, 外加一种非标准循环:goto [在c或c#中貌似出现过类型循环但是一般不建议用!] 一般格式为:delim ...

  10. mysql主备配置

    目录 mysql主备2 一.master配置:2 1. 修改配置文件 2 2. 登录添加账号并赋权限 2 3. 查看master信息 2 二.slave配置:2 1. 修改配置文件 2 2. 重启登录 ...