Python之路,Day20 = 异常处理、断言、socket之ftp协议
参考博客:http://www.cnblogs.com/metianzing/articles/7148191.html
1 异常处理 2 异常分为三个部分 3 Traceback:异常追踪 4 ValuError:异常类型 5 异常的值 6 7 格式: 8 try: 9 pass(可能出错的位置) 10 except ValuError: # 异常的类型 11 pass(输入出现这个异常时候的代码) 12 except KeyError as e1: # 把异常的值赋值给 e1 13 pass 14 except Exception: # 有异常执行 15 pass 16 else: # 没有异常执行 17 print("else") 18 finally: # 有没有异常都执行 19 pass 20 21 22 23 raise # 主动抛出异常 24 raise 自己的错误 25 26 27 28 断言 29 assert x > y 30 如果断言成功,执行下面的代码, 31 如果不成功,报错
一 客户端/服务器架构
即C/S架构,包括
1.硬件C/S架构(打印机)
2.软件C/S架构(web服务)
注:如果客户端用的是网页的话,我们把它称作 B/S架构
美好的愿望:
最常用的软件服务器是 Web 服务器。一台机器里放一些网页或 Web 应用程序,然后启动 服务。这样的服务器的任务就是接受客户的请求,把网页发给客户(如用户计算机上的浏览器),然 后等待下一个客户请求。这些服务启动后的目标就是“永远运行下去”。虽然它们不可能实现这样的 目标,但只要没有关机或硬件出错等外力干扰,它们就能运行非常长的一段时间。
C/S架构与socket的关系:
我们学习socket就是为了完成C/S架构的开发
二 osi七层
1 TCP/IP 协议不是两个协议,是一个协议族 2 应用层 3 会话层 4 表示层 5 传输层 6 7 网络层 8 9 链路层 10 11 物理层
端口作用:区分进程
0~1023是固定端口
IP相关
1 ip:192.168.1.1 2 192.168.119.0 网络号 3 192.168.119.255 广播地址 4 5 这个是 ipV4 6 7 ipv6 十六进制的,冒号分割 8 9 10 127.0.0.1 查看自己网络协议是否联通
socket相关
socket AF_INET:adress family internet SOCK_STREAM:tcp协议,流式协议 SOCK_DGRAM:udp协议,
tpc协议连接--服务端
1 import socket 2 import subprocess 3 phone_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 4 phone_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 5 phone_server.bind(('127.0.0.1',8080)) #绑手机卡 6 7 phone_server.listen(5) #开机 8 9 print('server run...') 10 while True: 11 conn,client_addr=phone_server.accept() #等电话 12 print('客户端: ',client_addr) 13 14 while True: #通讯循环 15 try: 16 cmd=conn.recv(1024) #收消息 17 18 res=subprocess.Popen(cmd.decode('utf-8'), 19 shell=True, 20 stdout=subprocess.PIPE, 21 stderr=subprocess.PIPE) 22 23 stdout=res.stdout.read() 24 stderr=res.stderr.read() 25 26 27 conn.sendall(stdout+stderr) 28 29 30 except Exception: 31 break 32 33 conn.close() #挂电话 34 35 phone_server.close() #关机
服务端套接字函数
s.bind() 绑定(主机,端口号)到套接字
s.listen() 开始TCP监听
s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来
客户端
1 import socket 2 phone_client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 3 4 # phone_client.connect(('127.0.0.1',8080)) #拨号 5 phone_client.connect(('192.168.16.131',8080)) #拨号 6 7 while True: #通讯循环 8 cmd=input('>>: ').strip() 9 if not cmd:continue 10 phone_client.send(cmd.encode('utf-8')) 11 12 cmd_res=phone_client.recv(1024) 13 # print(cmd_res.decode('gbk')) #windows 14 print(cmd_res.decode('utf-8')) #linux 15 16 17 phone_client.close()
客户端套接字函数
s.connect() 主动初始化TCP服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv() 接收TCP数据
s.send() 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.sendall() 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
s.recvfrom() 接收UDP数据
s.sendto() 发送UDP数据
s.getpeername() 连接到当前套接字的远端的地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字
面向锁的套接字方法
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 得到阻塞套接字操作的超时时间
面向文件的套接字的函数
s.fileno() 套接字的文件描述符
s.makefile() 创建一个与该套接字相关的文件
基于TCP的套接字
tcp服务端
1 ss = socket() #创建服务器套接字 2 ss.bind() #把地址绑定到套接字 3 ss.listen() #监听链接 4 inf_loop: #服务器无限循环 5 cs = ss.accept() #接受客户端链接 6 comm_loop: #通讯循环 7 cs.recv()/cs.send() #对话(接收与发送) 8 cs.close() #关闭客户端套接字 9 ss.close() #关闭服务器套接字(可选)
tcp客户端
1 cs = socket() # 创建客户套接字 2 cs.connect() # 尝试连接服务器 3 comm_loop: # 通讯循环 4 cs.send()/cs.recv() # 对话(发送/接收) 5 cs.close() # 关闭客户套接字
问题:
有的同学在重启服务端时可能会遇到
这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址(如果不懂,请深入研究1.tcp三次握手,四次挥手 2.syn洪水攻击 3.服务器高并发情况下会有大量的time_wait状态的优化方法)
解决方法:
1 #加入一条socket配置,重用ip和端口 2 3 phone=socket(AF_INET,SOCK_STREAM) 4 phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加 5 phone.bind(('127.0.0.1',8080))
1 发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决, 2 vi /etc/sysctl.conf 3 4 编辑文件,加入以下内容: 5 net.ipv4.tcp_syncookies = 1 6 net.ipv4.tcp_tw_reuse = 1 7 net.ipv4.tcp_tw_recycle = 1 8 net.ipv4.tcp_fin_timeout = 30 9 10 然后执行 /sbin/sysctl -p 让参数生效。 11 12 net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; 13 14 net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; 15 16 net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 17 18 net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间