python学习_网络编程
1、基础概念
架构:
c/s:客户端/服务端架构,充分发挥客户端的性能;可以应用于计算机硬件(打印机,文件服务器)也可以应用于计算机软件;
b/s:浏览器/客户端架构,统一了应用的接口;
Python支持:AF_UNIX,AF_NETLINK,AF_TIPC,AF_INET;
两台计算机之间的通信:网线,交换机;
同一台计算机两个py文件之间的通信:socket/import/文件读写
多个计算机之间的通信:交换机 (通信方式:广播,单播,组播)
更多个计算机之间的通信:交换机 路由器;
mac地址:物理地址,全球唯一,唯一的标示一台计算机;
ip地址:逻辑地址
端口:操作系统为本机的应用程序随机分配的一个端口(1-65535 0-1023不可用:预留给了系统)
网段:一个局域网内ip地址的范围;
子网掩码:用来计算网段的, 子网掩码 & ip地址-->判断是否在同一个网段;
TCP: 面向连接的,可靠的,面向字节流形式的,TCP本质上就是只允许同一时间,一个服务器和一个客户端保持连接,type=SOCK_STREAM;面向连接的通信提供序列化的,可靠的和不重复的数据交付;
UDP: 无连接的,不可靠的,面向数据报形式的,传输速度快,相对不可靠,允许一个服务器和多个客户端同时通信,type=SOCK_DGARM;与通信开始之前并不需要连接,消息是以整体发送的;
OSI模型:
物理层 光纤 集线器 网线 --传输电信号
数据链路层 交换机 网卡 网桥 --arp协议
网络层 路由器 三层交换机 --ip协议
传输层 四层交换机 四层路由器 --tcp/udp协议
应用层 http/https/ftp协议
TCP协议的三次握手:
一定是client发起请求,1、客户端发起请求连接服务器;2、服务器返回:接收到请求,并要求连接客户端;3、客户端回复:可以连接
四次挥手:
谁先发起断开连接的请求都可以,1、客户端发起断开连接的请求(表示次数我没有数据需要发送了,询问对方是否有数据要发送);2、服务端回复:我接收到你的请求了,3、服务端回复:我准备好断开连接了;4、客户单回复:收到信息,断开连接
ACK:确认收到
SYN: 请求连接的标示
FIN: 请求断开的标志
本地回环地址:127.0.0.1 本机地址,代表本地虚拟接口,只能被本机识别,不会被其他机器识别;
2、socket模块
IPC:进程间通信
是一个模块,一个套接字,是传输层和应用层之间的一个抽象层次
TCP协议编码流程:
粘包:可能发生粘包的问题(只有tcp可能会出现)
原因:发送端在发送数据的时候,接收端不知道如何去接收,造成的一种数据混乱的现象;接收方不知道消息之间的界限, 不知道一次性提取多少字节造成的;
在tcp协议中,有一个合包机制(nagle算法)将多次连续发送且间隔较小的数据,打包成一块数据进行传输,还有一个合包机制,在发送端,因为收到网卡MTU的限制,会将大的超过MTU限制的数据进行拆分,拆分成多个小的数据进行传输,当传输到目标主机的操作系统层的时候,会重新将多个小的数据合并成原本的数据;tcp粘包的拆包和合包机制发生在发送端;
解决粘包问题:
模块struct
struct.pack(type, num) type:num的类型。num一个数字,把一个数字打包成一个四字节的bytes
struct.unpack(type, r)解成原数字,结果是一个数组,原数字在下标为0de位置
在upd协议中,不会发现粘包的现象,在udp协议中一次收发数据大小的限制是65535 - ip包头(20) - udp包头(8) = 65507, 在数据链路层,MTU一般限制在1500,1500-20-8 = 1472, sentto(num) num>65507会报错,1472~65507之间的数据会在数据链路层被拆包,而且udp本身不是一个可靠的协议,所以在拆包之后,多个小的数据包在网络传输中,如果丢失一个,此次数据传输失败,所以num<1472是比较理想的状态;
服务端:
实例化对象
绑定ip地址和端口号
监听
接收客户端的连接
收法
关闭
客户端:
实例化对象
连接服务器
收发
关闭
# 服务端代码: import socket import time sk = socket.socket() sk.bind(('127.0.0.1', 8080)) sk.listen() while 1: conn addr = sk.accept() while 1: msg = conn.recv(1024) print(msg.decode('utf-8')) if msg.decode('utf-8') == 'q': break print(conn,addr) msg_my = input(">>>") conn.send(msg_my.encode('utf-8') if msg_my == 'q': break conn.close() time.sleep(1) break; sk.close()
# 客户端代码
import socket
sk = socket.socket()
sk.connect(('127.0.0.1', 8080))
while 1:
msg = input(">>>")
sk.send(msg.encode('utf-8'))
if msg == 'q':
break
msg_s = sk.recv(1024)
print(msg_s.decode('utf-8')
if msg_s.decode('utf-8') == 'q':
break
sk.close()
s.connect():z主动发起tcp服务器连接,s.connect_ex() 拓展版本,不会抛出异常,而是以错误码显示问题
s.listen(n):n是传入连接请求的最大数;
服务端接收到客户端的消息是空白的,说明客户端已经断开连接
udp协议及编码:
type = SOCK_DGARM
通信优势:可以和多个客户端通信
服务端流程:
实例化对象
绑定ip和端口号
收发数据
关闭
客户端流程:
实例化对象
收发数据
关闭
# udp服务端实现 import socket sk = socket.socket(type=socket.SCK_DGRAM) sk.bind(('127.0.0.1', 9090) while 1: msg_r, addr = sk.recvfrom(1024) name = msg_r.decode('utf-8').split(':')[0].strip() print(name) msg_s = input('>>>') sk,=.sendto(msg_s.encode('utf-8'), addr) sk.close() # udp客户端实现 import socket sk = socket.socket(type=socket.SOCK_DGARM) name = input(">>>") while 1: msg_s = input(">>>") info = name + ":" + info sk.sendto(info.encode('utf-8'), ('127.0.0.1', 9090) msg_r, addr = sk.recvfrom(1024) print(msg_r.decode('utf-8') sk.close()
socketServer:内置模块,主要是为了解决TCP协议中,服务器不能同时连接多个客户端的问题,是处在socket抽象层和应用层中的一层,比socket更贴近用户
import socketServer
class Mysocket(socketserver.BaseRequestHandler):
def handle(self):
# 收发的逻辑
msg = self.request.recv(1024).decode('utf-8')
print(msg)
self.request.send(msg.upper().encode('utf-8')
server = socketserver.TCPServer(('127.0.0.1', 8080), Mysocket) 固定写法
server.server_forever() 开启一个永久的服务
socket更多使用方法:
sk.setblocking(False-非阻塞状态/True-阻塞状态) 设置accept和recv两个方法的阻塞和非阻塞状态
sk.settimeout(seconds) 设置等待超时时间
conn.getpeername() 获取当前套接字的远端的地址
3、socketServer
标准库中的一个高级模块,socketServer模块处理程序的默认行为是接受连接,获取请求,然后关闭连接
4、Twister
是一个完整的事件驱动的网络框架,
4、面试:
1、TCP协议为什么比UDP协议可靠?
tcp是面向连接的,而udp是面向无连接的,tcp的通信过程中有一个ACK,(确认收到消息的一个标示);
2、路由器和交换机的区别?
交换机的主要功能是组织局域网,经过交换机内部处理解析信息之后,将信息以点对点,点对多的形式发送给固定端;路由器的主要功能:进行跨网段的数据传输,路由选择最佳路径;
5、网络协议
1、ftp协议
ftp协议底层只使用tcp而不适用udp
python中的ftp模块 ftplib模块
2、电子邮件(SMTP--简单邮件传输协议)
RFC规定,邮件可以没有正文,但一定要有标题,SMTP端口25,第一个用来下载邮件的协议POP(邮局协议),其他的有因特网消息访问协议(IMAP)--更适合多邮件客户端

浙公网安备 33010602011771号