mac 地址和 ip 地址
如果在网络中实现数据的传输,那么多台计算机该如何识别我们要传输的计算机呢?首先我们先举个例子,以我们以需要寻找一名同学为例:
所以在计算机中,我们定义了类似的概念:
局域网内传输 —— 交换机
而在普通的局域网中,是怎么实现同一局域网中多台机器传输数据呢?
局域网内部通信主要依靠交换机,而交换机只能够识别 mac 地址,当局域网内有计算机需要在局域网内传输时,它回首先将目标的 ip 地址和自己的 mac 地址传输给交换机,交换机将 ip 地址发送给局域网内的所有计算机,但只有目标计算机会回复并传输自己的 mac 地址,这时交换机已经缓存了传输方和接收方的 mac 地址,数据传输得以顺利进行。而再次传输时,也不需要重新寻找,因为交换机已经缓存了两边的 mac 地址。
这整个过程的协议称为 ARP 协议,即通过一台机器的 ip 地址获取到他的 mac 地址。
局域网间传输 —— 路由器
局域网之间的数据传输主要依靠路由器实现:
计算机1 --> 交换机1 --> 路由器网关1 --> 路由器网关2 --> 交换机2 --> 计算机2
而每个局域网都有一个网段:如 192.168.12.0、192.168.13.0 等,对应的是每个局域网内的计算机的 ip 地址可取范围为 192.168.12.0 - 192.168.12.255、192.168.13.0 - 192.168.13.255 等,但不绝对,根据子网掩码才能真正正确判断两台计算机是否在同一局域网内;每个字段对应一个网关,以刚刚的网段为例,对应地网关分别为 192.168.12.1、192.168.13.1。
ipv4 协议及 ipv6 协议
ipv4 协议:要求 ip 地址由四位点分十进制表示,如 192.169.12.87,每个点隔开的数字都是由八位二进制表示,即只能表示 0 - 255。
公网地址:我们需要自己申请购买的 ip 地址;
内网地址:保留字段属于内网地址,只存在于内部局域网,由于属于保留字段,不会与公网地址发生冲突;
保留字段:从上至下范围越来越大,计算机数量更多、更复杂的局域网会使用更大范围的保留字段:
192.168.0.0 - 192.168.255.255
172.16.0.0 - 172.31.255.255
10.0.0.0 - 10.255.255.255
特殊 ip 地址:127.0.0.1 本地回环地址,也属于保留字段。
ipv6 协议:是一种新提出的用于替代 ipv4 协议的新协议,它可以用冒分十六进制表示,表示范围非常大,号称可以为全世界的每一粒编子边上一个地址。
子网掩码
我们刚刚了解到,如果只保留最后一个点后的字段,局域网内如果超过 254 台计算机,将无法顺利为其分配 ip 地址,这时我们引入子网掩码的概念,它也是一个 ip 地址,可以用来判断两台机器是否在同一个局域网内,将子网掩码和 ip 地址进行按位与操作,最后结果相同的所有 ip 地址都属于一个局域网。如我们判断下列两个 ip 地址:192.168.13.1、192.168.12.1。
192.168.12.1
# 11000000.10101000.00000110.00000001
255.255.255.0
# 11111111.11111111.11111111.00000000
# 按位与
11000000.10101000.00000110.00000000 = 192.168.12.0
192.168.13.1
# 11000000.10101000.00000111.00000001
255.255.255.0
# 11111111.11111111.11111111.00000000
# 按位与
11000000.10101000.00000111.00000000 = 192.168.13.0
# 所以两个ip地址属于同一局域网
获取自己的 ip 地址
端口 port
一台电脑各个应用在接受和发送消息时都会接受附带相应的端口,来实现多个程序的信息传输,端口的范围为:0 - 65535。
一般在应用中,两个程序之间的通讯主要是服务端 server 和客户端 client 之间的通讯。
这种应用之间的通讯架构就是软件的网络开发架构:
TCP/IP 五层协议概述
OSI( Open System Interconnection ) 将网络通信的工作分为了七层,而 TCP/IP 协议将七层简略的分为了五层,主要包括:
TCP 协议
TCP( Transmission Control Protocol )需要先建立连接,才能够进行通信(类似打电话);
TCP 建立连接的三次握手和断开连接的四次握手:
# TCP建立连接过程-三次握手
# 全双工通信
# client -----请求连接服务SYN信号-----> server
# server ---允许连接ACK信号和SYN信号--> client
# client ------允许连接ACK信号--------> server
# TCP断开连接过程-四次挥手
# server -----请求断开连接FIN信号-----> client
# client ------允许断开ACK信号--------> server
# client -----请求断开连接FIN信号-----> server
# server ------允许断开ACK信号--------> client
# 挥手ACK和FIN挥手不能合并:因为要等待对面数据传输完毕
UDP 协议
不需要建立连接,就可以进行通信(类似于发短信);
基本导入操作
我们日常使用的很多“模块”其实都是包形式的,如 json、collections 等,我们在使用内置包的时候好像没有发现它与模块在导入与使用中有什么分别,我们现在来介绍一下自定义包的导入方法与规则,首先我们先进行包的数据准备,通过 Python 代码建立下列路径:
import os
os.makedirs(‘glance/api‘)
os.makedirs(‘glance/cmd‘)
os.makedirs(‘glance/db‘)
l = []
l.append(open(‘glance/__init__.py‘,‘w‘))
l.append(open(‘glance/api/__init__.py‘,‘w‘))
l.append(open(‘glance/api/policy.py‘,‘w‘))
l.append(open(‘glance/api/versions.py‘,‘w‘))
l.append(open(‘glance/cmd/__init__.py‘,‘w‘))
l.append(open(‘glance/cmd/manage.py‘,‘w‘))
l.append(open(‘glance/db/models.py‘,‘w‘))
map(lambda f:f.close() ,l)
这时我们已经有了一个包glance
,我们来尝试按照平时的方法直接导入包:
import glance
# glance.api.policy() # 报错
print(glance) # <module ‘glance‘ from ‘D:\\Python\\Python_Project\\day28\\包的导入\\glance\\__init__.py‘>
直接打印glance
后我们发现,它只是执行包内目录__init__
文件,并不相当于把这个包内所有的文件都导入,那么我们想直接导入某个包下的文件都有什么方法呢?
# 方式一 import
import glance.api.policy # dazhuang(仍然会执行glance\api包下的__init__文件)
glance.api.policy.get() # from policy.py
# 略微简化下:
import glance.api.policy as policy # dazhuang(仍然会执行glance\api包下的__init__文件)
policy.get() # from policy.py
# 方式二:
from glance.api import policy # dazhuang(仍然会执行glance\api包下的__init__文件)
policy.get() # from policy.py
# from glance import api.policy # 这样是不可以的,import后面不能带.
from glance.api.police import get # dazhuang(仍然会执行glance\api包下的__init__文件)
get() # from policy.py
绝对导入和相对导入
我们在包内的模块__init__
添加:from glance import api....
等,可以实现import glance
从而导入整个包内的模块的功能,但是目录关系的修改会引起报错,所以这被称为绝对导入;
而我们在__init__
添加:from . import api...
等,不会因为glance
目录的修改引起报错,所以又被称为相对导入,但相对导入的模块是无法被直接运行的。
所以我们在什么情况下使用绝对导入,又在什么情况下使用相对导入呢?
Python基础学习(27)网络编程基本概念 C/S架构与B/S架构 OSI七层协议 包的导入
原文:https://www.cnblogs.com/raygor/p/13382755.html