网络基础相关知识:
1, 架构
(1) C/S 架构 : client 客户端 和 server 服务器端
优势 : 能充分发挥PC机的性能
B/S 架构 : browser 浏览器 和 server 服务器端
其隶属于C/S架构, B/S架构统一了应用的接口
(2) 通信的事 :
1) 同一台电脑上的通信: 打开一个文件
2) 两台电脑通信: 一根网线
3) 多个电脑通信:
电脑1(源) 与电脑2(目标)
电脑1 发送一个请求帧, 其中包含了[电脑1 的 IP地址(192.168.1.11), 和电脑1 的MAC物理地址(XXXX)以及目标电脑2 的IP地址(192.1868.1.12)], 将请求发给交换机,交换机广播这条消息,给其他计算机,然后目标机接收到消息后,对比IP,确认自己是背照的机器,回复交换机信息(其中包含目标电脑的IP, MAC ,并将这些信息发送给 电脑1)交换机单播形式返回给电脑1
注意:
1, Mac地址: 是一个物理地址(每台电脑唯一),全球唯一
2, IP地址: 是一个由四位点分十进制组成. 他标志了计算机在网络中的位置.
3, 交换机的信号方式:
广播(吼一嗓子), 单播(一对一), 组播(一对多)
4, arp协议: 通过目标IP地址,获取目标的MAC(物理)地址的一个协议.
5, 端口: 操作电脑为本电脑上每一个运行的软件随机分配的一个端口,其他电脑上的程序可以通过端口获取这个程序.
6, 路由器: 链接不同网段, 路由是一个过程
7, 网关 : 类似于一个局域网的入口和出口.
8, 网段 : 一个局域网内的ip地址范围
9, 子网掩码: 子网掩码 & ip地址 得到网段
10, osi-----开放系统互联(Open System Interconnection)
osi五层模型
应用层 http, https, ftp
传输层
网络层 ip协议 路由器 三层交换机
数据链路层 arp协议 以太网交换机 网卡 网桥
物理层 传输电信号 集线器 网线 光纤
重点顺序:
arp协议
路由器与交换机的区别?
tcp协议和udp协议的特点,及tcp协议的编码
软件开发架构
osi五层模型
socket模块
socket 又叫做套接字
其有很多种类型,主要学习两种: TCP协议, UDP协议
TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket), 或插口
套接字用(IP地址 + 端口号) 表示
sk = socket.socket(family = AF_INET, type = SOCK_STREAM)
family有两种类型:
第一种:
AF_UNIX基于文件类型的套接字(早起socket[套接字]是源自于Unix系统而研发的一个功能, 主要是为了同一台电脑上, 多个程序之间通信.)
Unix系统的中心思想: 一切皆文件
第二种: AF_INET 基于网络类型的套接字
type:
一种是基于TCP协议 SOCK_STREAM
SOCK_STREAM套接口(流套接口)的性质(TCP协议的接口)
1,不保留任何消息边界
举一个例子:本地主机通过两次独立的write(2)调用向远程主机发送数据,
第一次本地进程写入25字节的数据,并通过套接口发送到远程进程,第二次再写入
30字节的数据发往远程进程,总共55字节的数据,而远程进程从套接口接收数据时,
将消息作为一个完整的单元来接收,或是通过若干次独立的读操作来将数据取走,
即接受端并不知道这55字节的数据是分25字节和30字节两次来发送的。
2, 有序性
可以保证接收的数据字节与发送的顺序完全一致(意味着通信之前必须建立一个链接)
3, 无错性
可以保证接收的数据在接受端被无错的接收, 如果有错误发生, 在尝试完所有的错
误恢复措施后仍无法消除错误, 所进行的错误恢复措施尝试是完全自动的, 不需要编程者的指导.
一种是基于UDP协议 SOCK_DGRAM
UDP协议: 不可靠的, 不面向连接的, 面向数据报的传输方式,速度快.(一般应用于网络电话等)
允许一个服务器同时和多个客户端通信.
SOCK_DGRAM套接口((UDP协议的接口))
特征:
1, 分组再发送后, 可能无序的到达接收端
2, 分组可能丢失, 如果发生丢失, 不会才去任何补救的措施, 而且接收端也不必直到分组丢失.
3, 数据报分组有尺寸大小的限制, 如果超出限制, 在某些路由器节点上就无法传送.
4, 分组是在不建立链接的情况下被发送到远程进程的.
TCP协议: 可靠地, 面向连接, 面向字节流的传输方式(可用于聊天室等.)
回环地址: 127.0.0.1 , 每个计算机都有的这么一个本机地址, 只能被本机识别, 不会被其他机器识别.
TCP的三次握手: 一定是client先发起的请求
a 客户端发起请求连接服务器
b 服务器返回: 接收到请求, 并要求链接客户端
c 客户端回复: 可以连接
四次挥手: 谁先发起断开连接都可以
a 客户端发起断开连接的请求:
意思是: 我想和你断开连接,我没有数据要继续发送了,但是如果你有数据要继续发送给我, 我可以继续接收.
b 服务器回复: 我接收到你的请求了,
c 服务器发送: 我已经准备好断开连接了
d 客户端回复: 收到你的信息, 断开连接
ACK : 确认收到
SYN : 请求链接的这么一个标识
FIN : 请求断开这么一个标识
3 pycharm带颜色输出:
\033[字体颜色;背景颜色m 数据 \033[0m
print('\033[32;43m abc ') print('abcsdasd \033[0m') print('asdfgggg')
TCP协议编程:
客户端(client):
1 import socket 2 3 sk = socket.socket() # 不传参数, 默认使用基于子类网络类型的套接字. 使用协议: TCP 4 sk.connect(('127.0.0.1', 65534)) # 链接 5 6 while 1: 7 msg = input('>>>') 8 sk.send(msg.encode('utf-8')) 9 if msg == 'q': 10 break 11 msg_r = sk.recv(1024).decode('utf-8') 12 if msg_r == 'q': 13 break 14 print(msg_r) 15 16 sk.close() # 结束链接
服务器端(server):
1 import socket 2 3 sk = socket.socket() 4 sk.bind(('127.0.0.1', 65534)) 5 sk.listen() 6 while 1: 7 conn, addr = sk.accept() 8 while 1: 9 msg_r = conn.recv(1024).decode('utf-8') 10 if msg_r == 'q': 11 break 12 print(msg_r) 13 msg_s = input('>>>') 14 conn.send(msg_s.encode('utf-8')) 15 if msg_s == 'q': 16 break 17 conn.close() 18 sk.close()
UDP协议编程:
客户端(client):
import socket sk = socket.socket(type=socket.SOCK_DGRAM) # UDP协议 实例化对象 name = input('请输入你的名字:') while 1: msg_s = input('>>>') info = name + ' : ' + msg_s sk.sendto(info.encode('utf-8'), ('127.0.0.1', 8090)) # 发送给谁的消息 msg_r, addr = sk.recvfrom(1024)# 接收来自于哪里的消息 print(msg_r.decode('utf-8')) if msg_r.decode('utf-8') == 'q': # 当输入'q'的时候退出交互 break sk.close()服务器端(server):import socket sk = socket.socket(type=socket.SOCK_DGRAM) # UDP协议 实例化对象 sk.bind(('127.0.0.1',8090)) # 绑定IP地址和端口号 dic = {'hanfei': '\033[43m',} while 1: msg_r, addr = sk.recvfrom(1024) # 接收消息 msg_r = msg_r.decode('utf-8') # 进行转码 if msg_r.split(':')[1].strip() == 'q': # 如果输入'q' 退出 break name = msg_r.split(':')[0].strip() color = dic.get(name, '') print('%s %s \033[0m' %(color, msg_r)) msg_s = input('>>>') sk.sendto(msg_s.encode('utf-8'),addr) # 发送消息 到服务器 sk.close()自定义一个socket模块
自定义socket模块代码1 import socket 2 3 4 class MySocket(socket.socket):# 继承自 socket文件中的socket类,此时socket就是父类 5 def __init__(self,encoding='utf-8'): 6 self.encoding = encoding 7 super(MySocket, self).__init__(type=socket.SOCK_DGRAM)# 执行父类socket中的__init__方法 8 9 def my_sendto(self,msg,addr): 10 return self.sendto(msg.encode(self.encoding),addr)# 调用父类中的sendto方法 11 12 def my_recvfrom(self,num): 13 msg_r,addr = self.recvfrom(num)# 调用父类的recvfrom方法 14 return msg_r.decode(self.encoding),addr引用自定义模块的服务器端(client)代码1 from My_UDP import MySocket 2 sk = MySocket() 3 sk.my_sendto('abcabc中国',('127.0.0.1',8080)) 4 sk.close()引用自定义模块的服务器端(server)代码1 from My_UDP import MySocket 2 sk = MySocket() 3 sk.bind(('127.0.0.1',8080)) 4 msg,addr = sk.my_recvfrom(1024) 5 print(msg) 6 sk.close()