一.网络基础相关知识
(1) 架构
a. C / S架构 : client客户端 和 server服务器端
优势 : 能充分发挥PC机的性能
b. B / S架构 : browser浏览器 和 server服务器 隶属于C/S架构
B / S架构 统一了应用的接口.
(2) 通信的事:
- 同一台电脑上两个py程序通信 : 打开一个文件
- 两个电脑如何通信 : 连一个网线
- 多个电脑通信 :
ex : 电脑1(源)要找电脑2(目标)
电脑1首先发送一个请求帧,期中包含(我的ip是192.168.1.1,我的mac地址是xxxxxxxx,我要找ip地址为192.168.1.2的主机),将此请求发送给交换机.
交换机要广播这条消息给其他所有的主机
目标主机接收到消息后,对比发现自己就是被找的主机,回复给交换机信息(我的ip地址是192.168.1.2,我的mac地址是yyyyyyyyy,请回复给ip地址为192.168.1.1,mac地址为xxxxxxx的主机)
交换机单播形式返回给源主机
知识点:
1.mac地址: 是一个物理地址,全球唯一,类似于身份证
2.ip地址: 是一个四位点分十进制,他标识了计算机在网络中的位置,类似以学号
3.交换机的通信方式:
广播:吼一嗓子
单播:一对一
组播:一对多
4.arp协议: 通过目标ip地址获取目标mac地址的一个协议
5.端口: 操作系统为本机上每一个运行的程序都随机分配一个端口,其他电脑上的程序可以通过端口获取到这个程序
ip地址+端口 能唯一找到某台电脑上的每一个服务程序
6.路由器: 连接不同网段
7 网关 : 类似于一个局域网的出口和入口
8 网段 : 一个局域网内的ip地址范围
9 子网掩码 : 子网掩码 & ip地址 得到网段
10.osi 五层模型:
互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层
每层运行常见物理设备
每层运行常见的协议
面试题: 交换机与路由器的区别?
交换机的主要功能是组织局域网,经过交换机内部处理解析信息之后,将信息以点对点,点多对的形式,发送给固定端
路由器的主要功能: 进行跨网段进行数据传输,路由选择最佳路径.
EX:
如果你需要将多台电脑连接到一根网线, 用交换机即可
如果你只有一个外网ip,但是你有好多台电脑需要上网, 用路由器即可
二.socket模块 (套接字)
有很多种类型,但是咱们只需要知道两种就可以了
sk = socket.socket(family = AF_INET, type=SOCK_STREAM)
family :
一种 : AF_UNIX基于文件类型的套接字(早期socket是源自于unix系统而研发的一个功能,主要是为了同一台电脑上,多个程序直接通信) unix系统的中心思想是 : 一切皆文件
一种 : AF_INET基于网络类型的套接字
type:
一种是基于TCP协议 SOCK_STREAM
一种是基于UDP协议 SOCK_DGRAM
tcp 协议 : 可靠的,面向连接的,面向字节流形式的传输方式
udp协议 : 不可靠的,不面向连接的,面向数据报的传输方式,但是它快
TCP协议编码流程:服务器端: 客户端实例化对象 实例化对象绑定IP地址和端口号 监听接收客户端的连接 连接服务器收发 收发关闭 关闭
回环地址: 127.0.0.1 每个计算机都有的这么一个本机地址,只能被本机识别,不会被其它机器识别
tcp三次握手: 一定是client先发起请求
a 客户端发起请求连接服务器
b 服务器返回 : 接收到请求,并要求连接客户端
c 客户端回复 : 可以连接
四次挥手: 谁先发起断开连接的请求都可以
a 客户端发起断开连接的请求:
意思是: 我想和你断开连接,我没有数据要继续发送了,但是如果你有数据需要发送,我可以继续接收
b 服务器回复 : 我接收到你的请求了
c 服务器发送 : 我已经准备好断开连接了
d 客户端回复 : 收到你的信息,断开连接
ACK : 确认收到SYN : 请求连接的这么一个标识FIN : 请求断开的这么一个标识
基于tcp协议的socket
tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端
server端
import socketsk = socket.socket()sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字sk.listen() #监听链接conn,addr = sk.accept() #接受客户端链接ret = conn.recv(1024) #接收客户端信息print(ret) #打印客户端信息conn.send(b'hi') #向客户端发送信息conn.close() #关闭客户端套接字sk.close() #关闭服务器套接字(可选)
client端
import socketsk = socket.socket() # 创建客户套接字sk.connect(('127.0.0.1',8898)) # 尝试连接服务器sk.send(b'hello!')ret = sk.recv(1024) # 对话(发送/接收)print(ret)sk.close() # 关闭客户套接字
基于UDP协议的socket
udp是无链接的,启动服务之后可以直接接受消息,不需要提前建立链接
简单使用
server端
import socketudp_sk = socket.socket(type=socket.SOCK_DGRAM) #创建一个服务器的套接字udp_sk.bind(('127.0.0.1',9000)) #绑定服务器套接字msg,addr = udp_sk.recvfrom(1024)print(msg)udp_sk.sendto(b'hi',addr) # 对话(接收与发送)udp_sk.close() # 关闭服务器套接字
client端
import socketip_port=('127.0.0.1',9000)udp_sk=socket.socket(type=socket.SOCK_DGRAM)udp_sk.sendto(b'hello',ip_port)back_msg,addr=udp_sk.recvfrom(1024)print(back_msg.decode('utf-8'),addr)
实现一个省去写编码解码的类,这个类继承socket
定义一个类:
import socketclass MySocket(socket.socket):# 继承自 socket文件中的socket类,此时socket就是父类 def __init__(self,encoding='utf-8'): self.encoding = encoding super(MySocket, self).__init__(type=socket.SOCK_DGRAM)# 执行父类socket中的__init__方法 def my_sendto(self,msg,addr): return self.sendto(msg.encode(self.encoding),addr)# 调用父类中的sendto方法 def my_recvfrom(self,num): msg_r,addr = self.recvfrom(num)# 调用父类的recvfrom方法 return msg_r.decode(self.encoding),addr
服务器端:
from My_UDP import MySocketsk = MySocket()sk.bind(('127.0.0.1',8080))msg,addr = sk.my_recvfrom(1024)print(msg)sk.close()
客户端:
from My_UDP import MySocketsk = MySocket()sk.my_sendto('abcabc中国',('127.0.0.1',8080))sk.close()