一、分层模型
OSI/RM(开放系统互联参考模型)
是由国际标准化组织提出来的一种网络互联模型,成为所有的销售商都能实现的开放网络模型.(OSI模型提供我们理解网络协议的内部运作)
OSI模型将网络通信工作分为7层,每一层为上一层服务,并为上一层提供一个访问的接口或者界面.
越下面的层,越靠近硬件;
越上面的层,越靠近用户.
7应用层
为操作系统或网络应用程序提供网络服务的接口.
6表示层
对上层数据或信息进行变化保证主机应用层的信息可以被另一个主机的应用程序理解.数据的加密,压缩,格式转换等等.
5会话层
管理主机之间的会话进程,建立管理终止进程之间的会话.
4传输层
负责对上层数据分段,并提供端对端,可靠和不可靠的传输.
数据单位 : 数据段
典型设备 : 网关
3网络层
负责对子网间的数据包进行路由选择.
数据单位 : 数据包
设备 : 路由器
2数据链路层
在不可靠的物理媒介上进行可靠的传输.
作用 : 物理地址寻址,数据成帧,流量控制,数据检错,重发等等
数据单位 : 帧
典型设备 : 交换机,网卡
1物理层
为上层协议提供了一个传输数据的物理媒体
数据单位 : bit
设备 : 光纤,双绞线,同轴电缆,集线器
TCP/IP模型
4应用层 : FTP,HTTP,TFTP,NFS
3传输层 : TCP,UDP
2网络层 : IP,ICMP,IGMP
1网络接口层 : ARP,RARP
ARP : 正向地址解析协议,通过已知的ip地址找到对应主机的MAC地址.
RARP : 反向地址转换协议.通过MAC地址确定ip地址.
ICMP : 互联网控制报文协议,用于在ip主机和路由器之间传递控制消息
IGMP : 是互联网组管理协议.
TCP : 传输控制协议
UDP : 用户数据报协议
TCP客户端
# tcp客户端
import socket
# 1.socket创建套接字
tcp = socket.socket() # 默认是tcp套接字
# 2.建立连接connect()
tcp.connect(('172.168.1.3', 8080))
# 3.send()发送数据
sendData = input('请输入要发送的数据:')
tcp.send(sendData.encode('gbk'))
# 4.recv()接收数据
recvData = tcp.recv(1024)
print('接收:', recvData.decode('gbk'))
# 5,关闭套接字close()
tcp.close()
TCP服务器
# tcp服务器
import socket
# 1.创建套接字
tcp = socket.socket()
# 2.绑定IP地址端口号
tcp.bind(('', 8080))
# 3.监听listen()
# 使用socket套接字创建的默认属性是主动,使用listen会被动
# 这样就可以接收别人来连接
tcp.listen(5) # 括号内表示一次可以同时接收的数量
# 4.连接accept()
# 如果有新的客户端来连接服务器,那么会产生一个新的套接字
# 专门为这个客户端服务
# clientSocket:用来为这个客户端服务的套接字
# clientAddr:客户端的IP地址和端口号
clientSocket, clientAddr = tcp.accept()
# 5.接收对方发送过来的数据
recvData = clientSocket.recv(1024)
print('客户端:', recvData.decode('gbk'))
# 6.发送一些数据给客户端
sendData = input('请输入要回复的:')
clientSocket.send(sendData.encode('gbk'))
# 7.关闭专门为这个客户端服务的套接字
clientSocket.close()
TCP案例_文件下载
import socket
tcp = socket.socket()
# 连接服务器
ip = input('请输入ip地址:')
port = int(input('请输入端口号:'))
tcp.connect((ip, port))
# 发送下载文件的请求
fileName = input('请输入要下载的文件名字:')
tcp.send(fileName.encode('gbk'))
# 接收文件的数据并且保存到文件中
recvData = tcp.recv(100000)
if recvData:
with open('[新]'+fileName, 'wb') as f:
f.write(recvData)
print('下载成功')
else:
print('下载失败')
# 关闭套接字
tcp.close()
二、网络中进程如何通信
tcp/ip中的网络层IP地址可以表示网络中的 主机,传输层”协议+端口号”可以标识主机中的进程.
利用ip地址+协议+端口号就可以标识网络中的进程.
使用tcp/ip协议的应用程序通常采用应用编程接口 : UNIX DSD的套接字(socket)
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket.建立网络通信至少要一对socket.
http提供了封装或者显示数据的具体格式;
socket就提供了网络通信的能力.
socket的创建
import socket
s = socket.socket(AddressFamily, type)
AddressFamily:可以选择AF_INET(用于网络进程通信)或者AF_UNIX(用于同一台计算机进程间通信).默认值为AF_INET
type:套接字类型,可以SOCK_STREAM(TCP协议)或者SOCK_DGRAM(UDP协议).默认值是SOCK_STREAM.
套接字使用流程和文件的使用类似:
1.创建套接字:s = socket.socket(AddressFamily, type)
2.使用套接字收/发数据
3.关闭套接字:s.close()
文件下载服务器
import socket
def getFileContent(fileName):
try:
with open(fileName, 'rb') as f:
fileContent = f.read()
return fileContent
except:
print('下载的文件不存在')
def main():
tcp = socket.socket()
tcp.bind(('', 8080))
tcp.listen(5)
# 等待客户端到来
while True:
clientSocket, clientAddr = tcp.accept()
print('新的客户来了:', str(clientAddr))
fileName = clientSocket.recv(1024).decode('gbk')
print('需要下载的文件是:', fileName)
# 获取文件数据
fileContent = getFileContent(fileName)
if fileContent:
# 发送文件数据给客户端
clientSocket.send(fileContent)
print('发送成功')
else:
print('发送失败')
# 关闭为这个客户端服务的套接字
clientSocket.close()
if __name__ == '__main__':
main()
udp : 用户数据报协议 udp提供不可靠的传输,只是把应用程序传给ip层的数据报发送出去,不能保证能够到达目的地.
udp在传输数据前不用在客户端和服务器之间建立一个连接,且没有超时重传机制,所以速度非常快.
udp是面向消息的协议,通信时不需要建立连接,数据传输自然不可靠,一般用于多点通信和实时的数据业务:语音广播,视频,qq,简单文件传送等等.
UDP客户端
# udp客户端
# socket是python内置的
import socket
# 1.socket()创建udp套接字
udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.通过sendto(要发送的数据, 发送的地址)发送数据
sendAddr = ('172.168.1.3', 8080)
sendData = input('输入要发送的数据:')
udp.sendto(sendData.encode('gbk'), sendAddr)
# 阻塞等到对方发送数据才能接收到
# 3.recvfrom()接收数据,括号内表示最大接收数据
recvData = udp.recvfrom(1024)
print('recv:', recvData)
# recvfrom返回值包含两部分内容:对方发送的数据,对方的地址
# 4.关闭套接字close()
udp.close()
UDP服务器
import socket
# udp服务端
# 1.创建套接字
udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.bind()绑定本机的ip地址和端口号
udp.bind(('172.168.1.3', 8080))
# 3.recvfrom()接收数据
recvData, recvAddr = udp.recvfrom(1024)
print(recvData.decode('gbk'))
# 4.sendto()发送数据
sendData = input('输入发送的数据:')
udp.sendto(sendData.encode('gbk'), recvAddr)
# 5.关闭套接字close()
udp.close()
UDP实战案例
import socket
def send(udp):
# 1.输入对方的ip地址和端口号
ip = input('请输入对方的ip地址:')
port = int(input('请输入对方的端口号:'))
# 2.输入要发送的数据
sendData = input('请输入要发送的数据:')
# 3.发送数据
udp.sendto(sendData.encode('utf-8'), (ip, port))
def recv(udp):
# 1.接收数据
recvData, recvAddr = udp.recvfrom(1024)
# 2.显示数据
print(recvAddr, ">>>>>>>", recvData.decode('utf-8'))
if __name__ == '__main__':
# 1.创建套接字
udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2.绑定端口号
# '':k可以直接获取当前计算机的ip地址
udp.bind(('', 8080))
# 3.根据用户的选择来调用发送/接收数据
while True:
print('1.发送数据')
print('2.接收数据')
num = input('请输入选择功能:')
if num == '1':
send(udp)
elif num == '2':
recv(udp)
else:
udp.close()
三、tcp协议(传输控制协议)
tcp是一种面向连接的,可靠的,基于字节流的传输层通信协议.
特点 :
1.采用发送应答机制 : tcp发送的每个报文段都必须等到接收方的应答才认为这个报文段传输成功
2.超时重传:
发送端发出一个报文段之后就启动一个定时器,如果在定时时间内没有收到应答就重新发送这个报文段.
为了保证不丢包,会给每个数据包一个序号,同时序号也保证了传送到接收端的包是按照顺序接收的.然后接收端接收到之后会对对应的包发回一个确认.如果发送端没有收到确认,那么会认为数据包丢失,将会重新传送.
3.错误校验
4.流量控制和阻塞管理
关于Python网络编程(一)的介绍今天就到这里啦,后续我会为大家介绍mysql数据库的相关知识哦~
关注我,带你领略Python的风采~😍😍😍