目录
软件的开发架构
-
软件开发架构:
-
开发软件,必须要开发一套客户端与服务端
- 服务端:24小时不间断服务
- 客户端:寻找服务
-
软件开发架构分为两种:
-
C/S架构:
- Client:客户端
- Server:服务端
- 举例:电脑上的qq,手机上的王者荣耀
- 优点:软件的使用稳定,并且可以节省网络资源
- 缺点:
- 若用户想在同一个设备上使用多个软件,必须下载多个客户端
- 软件的每一次更新也必须跟着重新下载更新
-
B/S架构:
-
Browser:浏览器(客户端)
-
Server:服务器
-
举例:在浏览器上输入某个软件的域名
-
优点:以浏览器充当客户端,无需下载多个软件,也无需用户下载更新软件版本,直接在浏览器上访问需要使用的软件
-
缺点:消耗网络资源过大,当网络不稳定时,软件的使用也会不稳定
-
-
-
网络七层协议
后期学习
- 网络编程-->并发编程-->数据库开发-->开发一套C/S架构的软件(仿优酷系统)
- 前端html/css/js-->web框架(网络编程/并发编程)-->开发一套B/架构的软件(bbs系统)
网络编程
-
网络编程发展历史
- 所有先进技术都源自军事,希望通过远程获取数据,所以出现了"网络编程"
- 早期如何实现远程通信
- 打电话-->电话线
- 电脑-->网线/网卡
- 实现远程通信必须具备条件
- 物理连接介质-->网卡
- 互联网协议---计算机之间沟通的介质
-
互联网协议
-
互联网协议又称网络七层协议,OSI七层协议,OSI是一个世界标准组织
-
OSI七层协议
-
应用层
http
ftp
-
表示层
-
会话层
-
传输层
TCP/UDP协议,都是基于端口工作的
- 端口号:标识电脑上某一个软件
- 端口号范围:0~65535
注意:
- 操作系统中,一般0~1024端口号都被默认使用了,不能使用
- 尽量使用8000之后的端口号
开发中常用的默认端口号(默写):
- mysql:3306
- mongodb:27017
- Django:8000
- Tomcat:8080
- Flask:5000
- Redis:6379
若想服务器与客户端进行通信,必须要建立连接,产生双向通道
- 一条是客户端往服务端发送消息,另一条是服务端往客户端发送消息
-
网络层
- IP地址:用于唯一标识计算机(局域网)的地址
- IP:点分十进制
- 最小值:0.0.0.0
- 最大值:255.255.255.255
- IPV4---电脑使用数量不多时出现的IP协议版本
- IPV6---扩展IP
- 本机IP:回环地址 127.0.0.1-->local host
-
数据链路层
-
数据链路层的"以太网协议"专门处理基于电信号发送的二进制数据
-
以太网协议
- 规定好电信号的分组方式
- 每一台连接网线的电脑都必须 要有一块"网卡"
- 网卡由不同的厂商生产:前六位表示厂商号,后六位表示流水号
-
交换机:让多台电脑连接到一起
-
基于以太网协议发送数据
- 特点:广播,单播
- 弊端:广播风暴,不能跨局域网通信
-
互联网
- 让局域网之间进行通信
-
-
物理连接层
- 基于电信号发送二进制数据
-
-
三次握手四次挥手---TCP协议的工作原理---TCP协议是一个流式协议---数据流去流回
-
三次握手建链接
-
建立双向通道
- listen:监听
- established:确认请求建立连接
-
发送数据
- write
- read
反馈机制:客户端往服务端发送消息,服务端必须要给客户端返回一个确认收到,否则,客户端会在某个时间内,不停发送,若服务端一直不返回确认收到,则客户端会取消发送并释放内存中的数据
-
-
四次挥手断链接
- 服务端收到断开请求时会先回复确认收到了断开请求的消息,在接收完客户端的剩余信息之后再发送确认断开请求
TIME_WAIT:时间等待
总结
- ip:用于唯一标识某一台计算机位置
- port:端口用于确认计算机上的一个应用软件
ip+port:世界上某一台电脑上的一个应用软件
socket的简单使用
什么是Socket?
- 是一个模块,可以写一套C/S架构的套接字
为什么要使用Socket?---可以写基于TCP协议的也可以写基于UDP协议的
- Socket套接字会封装好各层协议的工作,可以节省开发成本
如何使用?
import socket
服务端
import socket
# 默认指定TCP协议
server = socket.socket() # 实例化出一个socket对象---类比成买了一个手机
# 绑定服务端ip地址---参数:ip(测试使用回环地址) + 端口(自己设置,推荐8000以外
server.bind(('127.0.0.1', 9527))
# 类比成开机,等待接听
server.listen(5) # 半连接池
# 监听是否有消息,new_server_link相当于服务端往客户端的通道
new_server_link, address = server.accept() # 返回新的服务端链接和客户端的地址,return两个值时以元组接收
print(address)
# 通过新的服务端链接接收数据并打印
data = new_server_link.recv(1024).decode('utf8') # 可以接收1024字节的数据
print(data)
# 服务端通过新的服务端链接传输确认消息
new_server_link.send(b'hello small tank , i received')
# 断开连接
new_server_link.close()
# 关闭服务器
server.close()
客户端
import socket
# 类比成买手机
client = socket.socket()
# 往服务端拨号---参数:ip + port---寻找服务端---connect相当于客户端往服务端的通道
client.connect(('127.0.0.1', 9527))
# 客户端向服务端传输数据(二进制类型数据)
client.send('你好'.encode('utf8'))
# 客户端通过自己通道接收数据并打印
data = client.recv(1024)
print(data)
# 断开连接
client.close()
注意:客户端与服务端必须遵循:
- 一端send,一端receive,不能同时send或同时recevie,否则会阻塞但不会报错
半连接池+循环通信套接字
服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1', 9527))
server.listen(5) # 半连接池---可以等待5个用户+1个正在连接的用户共6个用户
while True: # 循环服务多个客户端
new_server_link, address = server.accept() # 返回新的服务端链接和客户端的地址,return多个值时以元组接收
print(address)
try: # 客户端非正常断开连接异常处理
while True:
data = new_server_link.recv(1024).decode('utf8')
print(data)
if data == 'q':
break
msg = input('server-->client:')
new_server_link.send(msg.encode('utf8'))
new_server_link.close()
except Exception as e:
print(e)
new_server_link.close()
客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 9527))
while True:
msg = input('client-->server:')
client.send(msg.encode('utf8'))
data = client.recv(1024).decode('utf8')
print(data)
if msg == 'q':
break
client.close()