day34 异常处理、断言、socket之ftp协议

 

 

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 时间
解决方案二
原文地址:https://www.cnblogs.com/alwaysInMe/p/7148309.html