网络编程_new
2023-04-18 17:25:04 4 举报
AI智能生成
python_网络编程基础
作者其他创作
大纲/内容
网络概念
1.局域网
局域网的概念
交换机
在同一个局域网内的机器由交换机负责通信
交换机只认识MAC地址
交换机功能:
广播
局域网内的某台设备给另一台设别发送消息,
由交换机负责广播通信,来寻找局域网内的目标设备
由交换机负责广播通信,来寻找局域网内的目标设备
组播
单播
通过MAC地址实现单播,在网卡上
不同局域网之间的通信
路由器
提供网关IP,同一个局域网内的所有设备共享同一个网关
不能访问本局域网之外的内网IP地址
子网掩码
0.0.0.0 ~255.255.255.255 之间,用来判断设备是不是在同一个局域网内
MAC地址
交换机遵循ARP协议,通过ip找MAC地址
端口port
用来区分同一设备上的不同应用服务
IP地址
IPV4协议
四位点分十进制
IPV6协议
公网地址
需要申请购买的地址
内网地址
192.168.0.0~192.168.255.255
172.16.0.0~172.31.255.255
10.0.0.0~10.255.255.255
本地回环地址
127.0.0.1
查看IP地址
ifconfig
mac/linux
ipconfig
win
ARP地址解析协议
通过IP找到MAC地址
2.网络开发架构
C/S架构
Client/Browser
B/S架构
Browser/Client
区别
C/S架构 可以离线使用,功能完善,安全性高
B/S架构 不用安装即可使用,统一PC端用户的入口
3.OSI协议
七层协议
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
五层协议
应用层
改层包含原七层协议中的:应用层、表示岑、会话层
python代码
传输层
概念
port端口
用来区分同一设备上的不同应用服务
tcp
效率低、面向链接、可靠、全双工
三次握手
四次挥手
udp
效率高、无链接、不可靠
设备
四层路由器
四层交换机
网络层
概念
ipv4
ipv6
设备
路由器
三层交换机
数据链路层
概念
mac地址
ARP协议
广播
单播
设备
网卡
二层交换机
物理层
4.传输层的TCP和UDP协议
TCP
1.需要先建立连接,然后才能通信
2.占用链接、可靠(消息不会丢失)、实时性高、慢、全双工通信
3.场景
语音、视频聊天
线下缓存高清电影、远程控制、发邮件等
UDP
1.不需要建立连接就可以通信
2.不占用链接、不可靠(消息因网络问题丢包)、块
TCP协议三次挥手四次握手过程
1.建立链接
三次握手
信号
SYN
ACK
2.断开链接
四次挥手
信号
FIN
ACK
3.为什么建立链接是三次握手而断开链接是四次挥手?
1.客户端请求建立链接时,服务端一次发送ACK信号加请求连接客户端的SYN信号,
导致省略了一次握手过程
导致省略了一次握手过程
2.四次挥手是因为要确保双发消息全部发送完成后,才能断开链接,避免出现一方的消息丢失
4.socket代码中的三次握手与四次挥手
socket模块
1.TCP协议通信过程
服务端
实例化socket对象
import socket
sk = socket.socket()
sk = socket.socket()
绑定IP 和 端口
sk.bind(('192.168.0.103', 9092))
# 此时sk对象中存储服务端的ip和端口
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.0.103', 9092)>
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.0.103', 9092)>
监听客户端链接
sk.listen()
与申请链接的客户端进行三次握手
conn, addr = conn.accept()
conn
包含服务端的ip和端口,以及与服务端建立链接的客户端的ip和端口
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.0.103', 9092), raddr=('192.168.0.103', 49444)>
addr
当前链接到的客户端的ip和端口,元组的形式
('192.168.0.103', 49444)
接收和发送消息
服务端接收和发送都是通过conn对象,
因为conn中存储这当前服务和当前链接的客户端的ip和端口
因为conn中存储这当前服务和当前链接的客户端的ip和端口
# 接收消息
msg = conn.recv(1024).decode('utf-8')
msg = conn.recv(1024).decode('utf-8')
# 发送消息
conn.send('你好'.encode('utf-8'))
conn.send('你好'.encode('utf-8'))
断开链接(四次挥手)
conn.close()
关闭服务
sk.close()
客户端
实例化socket对象
import socket
sk = socket.socket()
sk = socket.socket()
申请与服务端进行三次握手
sk.connect(('192.168.0.103', 9092))
sk
包含客户端的ip和端口,以及与服务端的ip和端口
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.0.103', 50613), raddr=('192.168.0.103', 9093)>
接收和发送消息
客户端接收和发送都是通过sk对象,
因为sk存储着客户端和当前链接的服务端的ip和端口
因为sk存储着客户端和当前链接的服务端的ip和端口
# 接收消息
msg = sk.recv(1024).decode('utf-8')
msg = sk.recv(1024).decode('utf-8')
# 发送消息
sk.send('你好'.encode('utf-8'))
sk.send('你好'.encode('utf-8'))
断开链接(四次挥手)
sk.close()
2.UDP协议通信过程
服务端
实例化socket对象
sk = socket.socket(type=socket.SOCK_DGRAM)
绑定 IP 和 端口
sk.bind(('192.168.0.103', 8081))
接收消息
msg, addr = sk.recvfrom(1024)
元组形式接收客户端发送的消息和客户端地址
发送消息
sk.sendto(msg, addr)
发送消息及接收的客户端地址
关闭服务
sk.close()
客户端
实例化socket对象
sk = socket.socket(type=socket.SOCK_DGRAM)
发送消息
sk.sendto(msg, addr)
给服务端发送消息及客户端地址
接收消息
msg = sk.recv(1024)
接收服务端发送的消息
3.编码实现
TCP
1.服务端一对一
2.服务端一对多通信
TCP协议时全双工通信,客户端和服务端都必须进行三次握手和四次挥手,才可以断开链接
UDP
1.服务端一对多通信
4.TCP/UDP协议socket流程图
5.TCP协议黏包现象
粘包产生的原因
TCP协议是流式传出,多条消息之间没有边界,并且再操作系统层面还有许多优化算法(缓存等)
发送端:两条消息都很短,发送的时间间隔也非常短
接收端:多条消息由于没有及时接收,而在接收端的缓存端堆在一起导致的粘包
粘包问题出现的本质:就是TCP协议流式传输没有边界,设置每次接收的边界值即可解决
网络最大带宽限制(MTU)
不同局域网之间的网络最大带宽限制为15000字节;
而最大带宽取决于网络传输过程中,MTU的最小值
解决TCP协议的粘包现象
1.自定义协议
发送方每次发送消息,先发送即将发送消息的字节长度,再发送内容
接收方每次先接收4个字节的长度,再将4字节长度转移称数值,然后再接收制定长度的字符,从而避免粘包
2.struct模块
pack('i', num: int)
将字符串的字节编码长度转成4个字节
unpack('i', str: byte)
将4位byte类型长度转换成数值,返回值时元组,元组的第一个元素时数值长度
3.自定义协议解决粘包问题代码(更新这张图片,struct模块还需要理解下)
0 条评论
下一页