11.15-11.18周末小结
一、软件开发架构
软件开发架构:规定了程序如何开发,比如开发的逻辑和功能等
1.C/S架构
client客户端和server服务端架构
通过下载客户端client软件,我们可以获得服务端高度定制化的功能 。
2.B/S架构
brower浏览器和server服务端架构
浏览器统一充当各个服务端的客户端 本质:bs架构本质上也是cs架构
通过浏览器brower软件,用来检索、展示以及传递Web信息资源。浏览器由大厂开发浏览器客户端,无法高度定制化,需要遵守浏览器的开发规则。
服务端的特点:
1.24小时不间断提供服务;
2.地址固定;
3.能够服务多个客人(满足高并发)
3.软件设计的方向
统一接口:各大互联网巨头正在做的事情
eg: 微信小程序(微信提供开发微信小程序的软件) ,支付宝小程序(各大程序接口)
二、网络编程简介
1.什么是网络编程
基于网络编程代码,能够实现数据的远程交互
2.学习网络编程的目的
能够开发cs架构的软件
3.网络编程的发展史
网络编程起源于美国军事,主要是想实现远程数据传输
而要想实现远程通信,第一个需要具备的条件就是:物理连接介质
4.网络编程必备条件
实现数据的远程交互必备的基础条件是物理连接介质
四:OSI七层协议模型和TCP/IP
四层协议
1.OSI七层协议模型
OSI(Open System Interconnect),即开放式系统互联。 这个开放式系统互联,是ISO(国际标准化组织)在1985年研究的网络模型。
ISO为了更好的使网络应用更为普及,推出了OSI参考模型。其含义就是推荐所有公司使用这个规范来控制网络。这样所有公司都有相同的规范,就能互联。
这个模型把网络通信的工作分为7层,分别物理层,数据链路层,网络层,传输层,会话层,表示层,应用层。
1至4层被认为是低层,这些层与数据移动密切相关。
5至7层是高层,包含应用程序级的数据。每一层负责一项具体的工作,然后把数据传送到下一层
2.OSI 七层协议 功能
- 应用层:为用户程序提供网路服务,使用的协议有
HTTP、TFTP, FTP, NFS, WAIS、SMTP
- 表示层:对信息进行语法处理,可确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取,使用的协议有
Telnet, Rlogin, SNMP, Gopher
- 会话层:通过传输层(端口号:传输端口与接收端口)建立不同的会话请求,主要是在系统之间里建立对话以及接收对话。使用的协议为
SMTP, DNS
- 传输层:接受上一层的数据,将上层的数据进行分割操作,在当到达目的地址的时候再进行重组,常常把这个数据叫做段。使用的协议
TCP,UDP
- 网络层:对在不同地理位置的网络中的两个主机系统提供连接和路径选择,使用的协议有
IP,IPv6, ICMP, ARP, RARP, AKP, UUCP
- 数据链路层:定义了数据化格式化传输,如何控制对物理介质的访问,这层提供信息的检测和纠正,以确保数据的可靠性传输,使用的协议有
FDDI, Ethernet, Arpanet, PDN, SLIP, PPP
- 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特,使用的协议有
IEEE 802.1A, IEEE 802.2到IEEE 802.11
3.TCP/IP 四层协议模型
众所周知,OSI参考模型是学术上和法律上的国际标准,是完整的权威的网络参考模型。而TCP/IP参考模型是事实上的国际标准,即现实生活中被广泛使用的网络参考模型。
OSI七层协议模型 | TCP/IP四层概念模型 | 对应的网络协议 |
---|---|---|
应用层 | 应用层 | HTTP、TFTP, FTP, NFS, WAIS、SMTP |
表示层 | 应用层 | Telnet, Rlogin, SNMP, Gopher |
会话层 | 应用层 | SMTP, DNS |
传输层 | 传输层 | TCP,UDP |
网络层 | 网络层 | IP,IPv6, ICMP, ARP, RARP, AKP, UUCP |
数据链路层 | 数据链路层 | FDDI, Ethernet, Arpanet, PDN, SLIP, PPP |
物理层 | 数据链路层 | IEEE 802.1A, IEEE 802.2到IEEE 802.11 |
1.物理连接层
第1层是物理层(也即[OSI模型]中的第一层也是最底层),物理层实际上就是布线、光纤、网卡和其它用来把两台网络通信设备连接在一起的东西。提供一个物理连接接口(网线口 无线网卡) 传递电信号。
物理连接层:主要用于确保计算机之间的物理连接介质 -->接收的数据都是二进制格式(在python中为bytes类型、二进制)
2.数据链路层
第2层是数据链路层,作用是将数据帧转换成而二进制位供1层处理。最重要的是我们应该理解网桥是什么,交换机可以看作是网桥,网桥仅关注以太网上的MAC地址。
数据链路层:
1)规定了0101的二进制电信号的分组方式
2)以太网协议 :规定了计算机在出厂的时候都必须有一块网卡,网卡上有一串数字;该数字相当于上计算机的身份证号码是独一无二的;该数据的特征(以太网地址/MAC地址)是12位16进制数据(前六位产商编号,后六位流水线号码)
- 广播:
主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发,所有主机都可以接收到所有信息(不管你是否需要),由于其不用路径选择,所以其网络成本可以很低廉。有线电视网就是典型的广播型网络,我们的电视机实际上是接受到所有频道的信号,但只将一个频道的信号还原成画面。在数据网络中也允许广播的存在,但其被限制在二层交换机的局域网范围内,禁止广播数据穿过路由器,防止广播数据影响大面积的主机。
- 交换机内部维护一张 MAC 地址表,记录着每一个 MAC 地址的设备,连接在其哪一个端口上
- 案例1
交换机看目标 MAC 地址(bb-bb-bb-bb-bb-bb)在地址表中并没有映射关系,于是将此包发给了所有端口,也即发给了所有机器。
之后,只有机器 B 收到了确实是发给自己的包,于是做出了响应,响应数据从端口 1 进入交换机,于是交换机此时在地址表中更新了第二条数据:
**MAC:bb-bb-bb-bb-bb-bb
端口:1**
- 经过该网络中的机器不断地通信,交换机最终将 MAC 地址表建立完毕
- 广播风暴
- 常见硬件
copy交换机:能够使接入该机器的所有计算机之间彼此互联
局域网:有交换机组成的网络
互联网:可以简单的理解为是多个局域网之间彼此互联
"""
基于mac地址的数据传输
1.广播风暴
2.mac地址不能跨局域网传输
mac地址
head中包含的源和目标地址由来:ethernet规定接入internet的设备都必须具备网卡,发送端和接收端的地址便是指网卡的地址,即mac地址。
mac地址:每块网卡出厂时都被烧制上一个世界唯一的mac地址,长度为48位2进制,通常由12位16进制数表示(前六位是厂商编号,后六位是流水线号)
"""
路由器:能够连接多个局域网并实现局域网之间的数据传输
3.网络层
第3层是网络层,网络层的作用就是选择合适的网间路由和交换结点, 确保数据及时传送,网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息-->源站点和目的站点地址的网络地址。有关路由的一切事情都在第3层处理。地址解析和路由是3层的重要目的。
(1)IP协议:规定了所有接入互联网的计算机都必须有一个IP地址,类似于身份证号
MAC地址是物理地址,可以看成是永远无法修改的
IP地址是动态分配的,不同的局域网内IP地址是不同的
IP地址特征:可以跨局域网传输,可以用来标识接入互联网的计算机
IP协议:规定了接入互联网的计算机都必须有一个IP地址用于唯一标识
IPV4版本
最小 0.0.0.0
最大 255.255.255.255
IPV6版本
能够表示出地球上每一粒沙子
- arp协议
将IP地址转换成mac地址(基于网络请求)
arp协议 ——查询IP地址和MAC地址的对应关系
地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。
主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址。
收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。
地址解析协议是建立在网络中各个主机互相信任的基础上的,网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗。ARP命令可用于查询本机ARP缓存中IP地址和MAC
- 路由器
路由器(Router),是连接因特网中各局域网、广域网的设备,它会根据信道的情况自动选择和设定路由,以最佳路径,按前后顺序发送信号。 路由器是互联网络的枢纽,"交通警察"。目前路由器已经广泛应用于各行各业,各种不同档次的产品已成为实现各种骨干网内部连接、骨干网间互联和骨干网与互联网互联互通业务的主力军。路由和交换机之间的主要区别就是交换机发生在OSI参考模型第二层(数据链路层),而路由发生在第三层,即网络层。这一区别决定了路由和交换机在移动信息的过程中需使用不同的控制信息,所以说两者实现各自功能的方式是不同的。
路由器(Router)又称网关设备(Gateway)是用于连接多个逻辑上分开的网络,所谓逻辑网络是代表一个单独的网络或者一个子网。当数据从一个子网传输到另一个子网时,可通过路由器的路由功能来完成。因此,路由器具有判断网络地址和选择IP路径的功能,它能在多网络互联环境中,建立灵活的连接,可用完全不同的数据分组和介质访问方法连接各种子网,路由器只接受源站或其他路由器的信息,属网络层的一种互联设备。
- 子网掩码
所谓”子网掩码”,就是表示子网络特征的一个参数。它在形式上等同于IP地址,也是一个 32位二进制数字,它的网络部分全部为1,主机部分全部为 0。比如,IP地址 172.16.10.1,如果已知网络部分是前24位,主机部分是后8位,那么子网络掩码就是11111111.11111111.11111111.00000000,写成十进制就是 255.255.255.0。
知道”子网掩码”,我们就能判断,任意两个IP地址是否处在同一个子网络。方法是将两个IP地址与子网掩码分别进行AND运算(两个数位都为 1,运算结果为 1,否则为 0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。
- 如果源 IP 与目的 IP 处于一个子网,直接将包通过交换机发出去。
- 如果源 IP 与目的 IP 不处于一个子网,就交给路由器去处理。
4.传输层
第4层是处理信息的传输层,第4层的数据单元也称作数据包(packets,第4层提供端对端的通信管理。
(1)PORT协议(端口协议):
给应用程序分配端口号,通过端口号来标识一台计算机上面的某一个应用程序
端口号的范围:0-65535
端口号的特征:动态分配
端口号建议:
端口号:0-1023 系统默认需要使用
端口号:1024-8000 常见软件的端口号
(2)URL:统一资源定位符
uniform resource locator
网址:本质是由IP和PORT组成的
IP+PORT:能够定位全世界独一无二的一台计算机上面的某一个应用程序
(3)域名解析:将网址解析成IP+PORT
IP:PORT ip地址:端口
180.101.49.13:80 --> 百度的IP地址:百度的PORT端口
(4)TCP与UDP协议
TCP与UDP协议规定通信方式(数据交互的方式),彼此之间通信要有通信的通道,双方都必须能和对方发消息
端口号(port):能够唯一标识一台计算机上面正在运行的一款应用程序
端口号在同一台计算机同一时刻不能重复
- 端口
我们知道,一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区分不同的服务的。
- 总结
ip+port 127.0.0.1:8080
能够唯一标识世界上某一台接入互联网的计算机上面的某一个正在运行的应用程序
4.1.TCP协议
流式协议 可靠协议
当应用程序想通过TCP协议实现远程通信时,彼此之间必须先先建立双向通信通道,基于该双向通道实现数据的远程交互,该双向通道直到任意一方主动断开才会失效
三次握手 建立链接
重要状态
listen监听态:等待对方发请求
syn_rcvd态:忙于恢复确认建立请求
# 洪水攻击:服务端在同一时间接收到了大量的要求建立链接的请求
四次挥手 断开链接
不能合并成三次
4.2.三次握手
1)TCP协议:三次握手建链接,四次挥手断链接
可靠传输,TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的长度,以确保单个TCP数据包不必再分割。
三次握手建链接: 建立双向通道的过程称之为三次握手,建立通道的发起者可以是客户端也可以是服务端,下面我们就以客户端先主动发起为例
1. TCP协议也称为可靠协议,数据不容易丢失,造成数据不容易丢失的原因不是因为有双向通道,根本原因是因为有反馈机制。
2.反馈机制:TCP协议,在发送消息的过程中,会将消息复制一份副本,直到对方回应消息收到后反馈才会删除副本,否则会在一定时间内反复发送(反馈机制有时间限制,超过这个时间限制也会删除副本)。
3.洪水攻击:同一时间有大量的客户端请求建立链接,会导致服务端一直处于SYNZ_RCVD状态(避免洪水攻击,可以在服务端前建立缓冲池,分流用户请求)
4.服务端如何区分建立链接的请求:seq = x 表示不同的客户端请求的标识,区分不同的客户端请求
-
客户端会朝服务端发送一个请求询问服务端:"我能不能挖一条通往你家的地道"
-
服务端收到请求,回复说:"好吧 你挖吧",由于TCP是双向通道,客户端挖向服务端的通道只能给客户端朝服务端发消息使用,服务端要向给客户端发消息是没办法走这一条通道的,需要自己挖一条通往客户端的通道
所以服务端在回复同意客户端挖通道的同时还会问一句:"那我能不能也挖一条通往你家的通道"
-
客户端收到服务端请求后客户端到服务端的通道就挖成功了,然后也会同意服务端的请求,服务端挖向客户端的通道也会成功
总结:之所以称之为三次握手就是因为中间的服务端的同意,和请求合并成了一次请求
- 三次握手状态内容
所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个包。
三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手。
第一次握手(SYN=1, seq=x):
客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。
发送完毕后,客户端进入 SYN_SEND 状态。
第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD 状态。
第三次握手(ACK=1,ACKnum=y+1)
客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1
发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。
4.3.四次挥手
建立一个连接需要三次握手,而终止一个连接要经过四次握手
当服务端或者客户端不想再与对方进行通信之后,双方任意一方都可以主动发起断开链接的请求,我们还是以客户端主动发起为例
-
客户端由于已经没有任何需要发送给服务端的消息了,所以发起断开客户端到服务端的通道请求
-
服务端收到该请求后同意了 至此客户端到服务端的单项通道断开
-
服务端这个时候不会立刻朝客户端发器请求说那我也断开到你家的通道吧,服务端需要想想我手上还有没有需要发送给客户端的消息,如果还有的话,那我不能立马断开,先把数据发完才能断
等服务端检查完毕之后发送也没有数据要给客户端了,这个时候就会朝客户端发起断开服务端到客户端的通道请求
-
客户端同意该请求,至此四次挥手完成
总结:挥手必须是四次,中间的两次不能合并成一次,原因就在于需要检查是否还有数据需要给对方发送
- 四次挥手状态内容
TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),也叫做改进的三次握手。客户端或服务器均可主动发起挥手动作,在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。
第一次挥手(FIN=1,seq=x)
假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。
发送完毕后,客户端进入 FIN_WAIT_1 状态。
第二次挥手(ACK=1,ACKnum=x+1)
服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。
发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。
第三次挥手(FIN=1,seq=y)
服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。
发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。
第四次挥手(ACK=1,ACKnum=y+1)
客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。
服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。
客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。
4.5.UDP协议
不可靠协议,也称为数据报协议。当应用程序希望通过UDP与一个应用程序通信时,传输数据之前源端和终端不建立连接。
当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。数据发送没有通道的概念 发送出去了就不管了
不可靠传输,”报头”部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包。
4.6.协议特性
无连接:通信不需要建立连接,只要知道对方地址就可以发送数据
不可靠:不能保证数据是否可以安全、有序的到达对端
面向数据报:一个数据报的最大大小为64k,加上udp数据报头部信息一共64位还要占8个字节,因此数据大小不能超过64k-8。
4.7.UDP 的优点
相对TCP更加简单、便捷,没有三次握手四次挥手洪水攻击等等,比 TCP 稍安全。
UDP 没有 TCP 的握手、确认、窗口、重传、拥塞控制等机制,UDP 是一个无状态的传输协议,所以它在传递数据时非常快。没有 TCP 的这些机制,UDP 较 TCP 被攻击者利用的漏洞就要少一些。但 UDP 也是无法避免攻击的,比如:UDP Flood 攻击。
4.8.UDP 的缺点
不可靠,不稳定。
因为 UDP 没有 TCP 那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。
基于上面的优缺点,那么,TCP 和 UDP 的应用场景都有哪些呢?
4.9.应用场景
当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如 HTTP、HTTPS、FTP 等传输文件的协议,POP、SMTP 等邮件传输的协议。
在日常生活中,常见使用 TCP 协议的应用如下: 浏览器用的 HTTP, FlashFXP 用的 FTP,Outlook 用的 POP、SMTP,Putty 用的 Telnet、SSH,QQ 文件传输。
4.10.1 UDP 应用场景
当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用 UDP。
比如,日常生活中,常见使用 UDP 协议的应用如下:QQ 语音,QQ 视频,TFTP 等。有些应用场景对可靠性要求不高会用到 UPD,比如长视频,要求速率。
4.10.2 TCP与UDP对比
TCP 的优点:可靠,稳定。
TCP 的可靠体现在 TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。
TCP 的缺点:慢,效率低,占用系统资源高,易被攻击。
TCP 在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的 CPU、内存等硬件资源。
而且,因为 TCP 有确认机制、三次握手机制,这些也导致 TCP 容易被人利用,实现 DOS、DDOS、CC 等攻击。
4.10.3 总结TCP与UDP
1、TCP 面向连接(如打电话要先拨号建立连接); UDP 是无连接的,即发送数据之前不需要建立连接。
2、TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付。
3、TCP 面向字节流,实际上是 TCP 把数据看成一连串无结构的字节流;UDP 是面向报文的。UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条 TCP 连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
5、TCP 首部开销 20 字节;UDP 的首部开销小,只有 8 个字节。
6、TCP 的逻辑通信信道是全双工的可靠信道,UDP 则是不可靠信道。
TCP协议是TCP/IP协议栈中的传输层的典型协议,叫传输控制协议,面向连接,可靠传输,提供字节流服务。
TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP协议是TCP/IP协议栈中的传输层的典型协议,叫用户数据报协议,无连接,不可靠,提供数据报传输服务。
UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快
早期的QQ使用的就是UDP
5.socket概念
1.Socket通信
Socket是应用层与TCP/IP协议簇通信的中间抽象层,是一组接口。在设计模式中其实就是门面模式。Socket将复杂的TCP/IP协议簇隐藏在接口后面,对于用户而言,一组接口即可让Socket去组织数据,以符合指定的协议。
socket 其实就是操作系统提供给程序员操作「网络协议栈」的接口,说人话就是,你能通过socket 的接口,来控制协议找工作,从而实现网络通信,达到跨主机通信。
6.应用层
应用程序收到"传输层"的数据,接下来就要对数据进行解包。由于互联网是开放架构,数据来源五花八门,必须事先规定好通信的数据格式,否则接收方根本无法获得真正发送的数据内容。“应用层"的作用就是规定应用程序使用的数据格式,例如我们TCP协议之上常见的Email、HTTP、FTP等协议,这些协议就组成了互联网协议的应用层。
应用层提供了诸多的协议,比如HTTP、FTP、POP3、IMAP等协议,用于约定特殊应用在应用层封装与解包通信的格式。保证统一,避免出现类似于外国人听不懂粤语,俄罗斯人听不懂德语等语言不互通问题。
如下图所示,发送方的HTTP数据经过互联网的传输过程中会依次添加各层协议的标头信息,接收方收到数据包之后再依次根据协议解包得到数据。xxxxxxxxxx 应用程序收到"传输层"的数据,接下来就要对数据进行解包。由于互联网是开放架构,数据来源五花八门,必须事先规定好通信的数据格式,否则接收方根本无法获得真正发送的数据内容。"应用层"的作用就是规定应用程序使用的数据格式,例如我们TCP协议之上常见的Email、HTTP、FTP等协议,这些协议就组成了互联网协议的应用层。应用层提供了诸多的协议,比如HTTP、FTP、POP3、IMAP等协议,用于约定特殊应用在应用层封装与解包通信的格式。保证统一,避免出现类似于外国人听不懂粤语,俄罗斯人听不懂德语等语言不互通问题。如下图所示,发送方的HTTP数据经过互联网的传输过程中会依次添加各层协议的标头信息,接收方收到数据包之后再依次根据协议解包得到数据。都是人为自定义的协议标准 可遵循可不遵循HTTP协议 FTP协议 ...
六:七层模型传输数据过程
1.OSI 七层模型数据传输过程如下
2.数据包传输过程
3.IP层传输单位是IP分组,属于点到点的传输;TCP层传输单位是TCP段,属于端到端的传输
七:七层OSI
八、网络相关专业名词
计算机之间想要实现数据集交互必须要‘连接’到一起
1.交换机
能够将计算机互连在一起
2.广播
首次查找接入同一个交换机的其他计算机,需要进行广播
3.单播
首次被查找的计算机回应查找它的计算机,叫做单播
4.广播风暴
接入同一台交换机的多台计算机同时进行广播
5.局域网
单个交换机组成的网络,可以看作是一个局域网;同一个局域网中的计算机,可以基于MAC地址作数据交互(不是一个局域网无法直接通过MAC地址访问)
6.广域网
可以简单的理解为范围更大的局域网
7.互联网
由所有的局域网、广域网连接到一起形成的网络
互联网 <-- 广域网 <-- 局域网
8.路由器
不同的局域网之间是无法直接实现数据交互的,需要路由器连接并分配ip地址 (路由器可以实现不同局域网之间的数据交互)
路由器:常见路由器、基站(4G 5G网络)
9.网关Gateway
网关(Gateway)又称网间连接器、协议转换器。
网关在网络层以上实现网络互连,是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间。仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。
网关是一个翻译器,网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同层--应用层
九、socket编程
1.简介
socket上应用层与TCP/IP协议通信中间的软件抽象层,帮助我们编写基于网络进行数据交互的程序,否则意味着需要自己通过代码来控制OSI七层来进行数据传输。
2.参数
socket是基于C/S架构的,也就是说进行socket网络编程,通常需要编写两个py文件,一个服务端,一个客户端。 首先,导入Python中的socket模块:
import socket
sock = socket.socket([family[, type[, proto]]])
-
family: 套接字家族,可以使
AF_UNIX
或者AF_INET
。 -
type: 套接字类型,根据是面向连接的还是非连接分为
SOCK_STREAM
或SOCK_DGRAM
,也就是TCP和UDP的区别。 -
protocol: 一般不填默认为0。
-
下面是具体的参数定义:
socket类型 | 描述 |
---|---|
socket.AF_UNIX | 只能够用于单一的Unix系统进程间通信 |
socket.AF_INET | IPv4 |
socket.AF_INET6 | IPv6 |
socket.SOCK_STREAM | 流式socket , for TCP |
socket.SOCK_DGRAM | 数据报式socket , for UDP |
socket.SOCK_RAW | 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。 |
socket.SOCK_SEQPACKET | 可靠的连续数据包服务 |
创建TCP Socket: | s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) |
创建UDP Socket: | s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) |
3.socket套接字方法
通过s = socket.socket()
方法,我们可以获得一个socket对象s,也就是通常说的获取了一个“套接字”,该对象具有一下方法:
方法 | 描述 |
---|---|
服务器端方法 | |
s.bind() | 绑定地址(host,port)到套接字,在AF_INET下,以元组(host,port)的形式表示地址。 |
s.listen(backlog) | 开始监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 |
s.accept() | 被动接受客户端连接,(阻塞式)等待连接的到来,并返回(conn,address)二元元组,其中conn是一个通信对象,可以用来接收和发送数据。address是连接客户端的地址。 |
客户端方法 | |
s.connect(address) | 客户端向服务端发起连接。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 |
s.connect_ex() | connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 |
公共方法 | |
s.recv(bufsize) | 接收数据,数据以bytes类型返回,bufsize指定要接收的最大数据量。 |
s.send() | 发送数据。返回值是要发送的字节数量。 |
s.sendall() | 完整发送数据。将数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 |
s.recvform() | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收的数据,address是发送数据的套接字地址。 |
s.sendto(data,address) | 发送UDP数据,将数据data发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 |
s.close() | 关闭套接字,必须执行。 |
s.getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 |
s.getsockname() | 返回套接字自己的地址。通常是一个元组(ipaddr,port) |
s.setsockopt(level,optname,value) | 设置给定套接字选项的值。 |
s.getsockopt(level,optname[.buflen]) | 返回套接字选项的值。 |
s.settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) |
s.gettimeout() | 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 |
s.fileno() | 返回套接字的文件描述符。 |
s.setblocking(flag) | 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。 |
s.makefile() | 创建一个与该套接字相关连的文件 |
4.代码实现tcp协议
(1)服务端
"代码优化"
import socket
from socket import SOL_SOCKET, SO_REUSEADDR
# 1 产生一个socket对象并指定采用的通信协议TCP
server = socket.socket() # 括号内不写参数,默认TCP协议 ,family = AF_INET基于网络的套接字, type = SOCK_STREAM流式协议即
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 8080)) # 127.0.0.1为本地回环地址,只有自己的电脑可以访问
server.listen(5)
while True: # 添加循环,保证可以多客户端申请访问,在连接一个客户端的同时,其他客户端可以在半连接池中等待
sock, addr = server.accept() # accept方法返回sock, addr
while True: # 添加循环,可以循环接收客户端发送的消息
try: # 添加异常处理2 windows系统: 当当前客户端不发消息了,就重新接收别的客人的消息,防止win系统报错
data = sock.recv(1024) # 接收客户端发送过来的消息,1024字节
if len(data) == 0: # 异常处理1 macos系统:当客户端发送空消息,则重新接收下一条消息
break
print(f'来自客户端{addr}的字节>>>', data.decode('utf8'))
msg = input('消息发送:').strip()
sock.send(msg.encode('utf8')) # 给客户端发消息,消息必须是bytes类型
except BlockingIOError: # 异常处理
break
(2)客户端
client = socket.socket()
client.connect(('127.0.0.1', 8080))
while True: # 添加循环:可以多次发消息
msg = input('发送给服务端>>>:').strip()
if len(msg) == 0:
print('不能发空消息')
continue
client.send(msg.encode('utf8'))
data = client.recv(1024)
print('来自客户端的消息>>>', data.decode('utf8'))
优化内容:
1.聊天内容自定义:
采用input语句来获取消息,可以自定义消息
2.重复发送消息:
添加循环,将聊天的部分用循环包起来
3.用户发送消息不能为空:
本质其实是两边不能都是recv或者send,一定是一方收一方发
4.服务端多次重启可能报错:macos系统
Address already in use
解决方式1:改端口号
解决方式2:博客里面代码拷贝即可
5.当客户端异常断开的情况下 如何让服务端继续服务其他客人
windows服务端会直接报错
mac服务端会有一段时间反复接收空消息延迟报错
异常处理、空消息判断
十、黏包现象
1.黏包现象简介
基于tcp协议传输数据的时候,如果接收端单次接收的数据长度小于发送的总长度,则会导致部分数据无法接收全,在第二次接收的时候会继续接收上次没接收完的数据,导致数据接收变混乱,这种现象就叫做半包
或者连续发送小数据的时候,接收端一次接收所有收据,也导致数据接收变混乱,也叫黏包现象。
2.黏包现象产生的原因
1.接收数据时无法知道发送的数据的长短
2.TCP也称为流式协议:数据就像水流一样,没有间隔(TCP会针对数据量较小且发送间隔较短的多余数据一次性合并打包发送),并且在发送的数据传输的过程中还有缓存机制来避免数据丢失。
3.避免黏包现象的关键
如何确定即将接收的数据的大小,就是我们解决黏包现象的关键
解决的办法就是,客户端在发送数据之前先发送一条数据,告诉服务端这条数据长度是多少,服务器接收到这个数据之后反馈成功,客户端再发送真实数据。这样服务端就可以通过之前接收到数据长度来接收数据。
十一、struct模块
1.struct模块
简介:该模块可以把一个类型,如数字,转换成固定的长度的bytes
struct模块中模式代号与对应传递的python类型
2.struct模块制作报头
(1)客户端:
1 制作真实数据的信息字典(数据长度、简介、名称)
2 利用struct模块制作字典的报头
3 发送固定长度的报头(解析出来的是字典的长度)
4 发送字典数据
5 发送真实数据
(2)服务端:
1 接收固定长度的字典报头
2 解析出字典的长度并接收
3 通过字典获取到真实的数据的各项信息
4 接收真实数据的长度
十二、并发
操作系统的发展史就是cpu提升利用率的过程
1.多道技术与单道技术
单道技术:所有的程序排队执行,过程中不能重合
多道技术:利用空闲时间提前准备其他数据,最大化提升cpu利用率
2.多道技术详细
1.切换
计算机的cpu在两种情况下会切换:
(1)程序有IO操作:输入\输出
(2)程序长时间占用cpu
2.保存状态
cpu每次切换走之前都需要保存当前操作的状态,下次切换回来基于上次的进度继续执行
十三、进程理论
1.进程与程序的区别
程序:一堆死还没有被运行起来的代码
进程process:正在运行的程序---代码被运行起来了
2.进程的并行与并发
并行:多个进程同时执行,必须要有多个CPU参与
并发:利用多道技术
3.进程的三状态
就绪态:所有的进程在被cpu执行之前都必须进入就绪态准备
运行态:cpu正在执行该进程
阻塞态:cpu运行过程中出现了IO操作会进入阻塞态,阻塞态无法直接接入运行态,必须经过就绪态才能加入运行态
十四、同步与异步、阻塞与非阻塞
1.同步阻塞
效率最低,单任务按顺序执行
2.同步非阻塞
多任务,定时查看任务执行状态
3.异步阻塞
单任务,自动提交任务执行状态。
4.异步非阻塞
效率最高,提交完任务之后不原地等待,直接去做其他事情,并且cpu也不会被剥夺走。多任务,自动提交任务执行状态,合理分配,最大化利用资源。
十五、创建进程与方法
1.创建进程的方法
(1)方式1:鼠标双击创建进程
系统中,鼠标双击软件图标,创建进程
(2)方式2:代码创建进程
python代码创建进程,使用multiprocessing模块中的类Process来创建进程
1 生成类Process的对象创建进程
# 创建进程模块multiprocessing
from multiprocessing import Process
import time
def task(name,age):
print('task is running',name)
time.sleep(3)
print('task is over',age)
if __name__ == '__main__':
"让一个函数在同一时间执行多次"
p1 = Process(target=task,args=('jason',18))
p1.start() # 异步操作:子进程 告诉操作系统创建一个新的进程,并在该进程中执行task函数
# task() # 同步操作
print('主进程')
==========运行结果===============
主进程
task is running jason
# 3s后
task is over 18
2 编写类继承Process,来创建子进程
from multiprocessing import Process
import time
class MyProcess(Process):
def run(self):
print('run is running')
time.sleep(3)
print('run is over')
if __name__ == '__main__':
obj = MyProcess()
obj.start()
print('主进程')
==========运行结果===============
主进程
run is running
run is over
2.进程中的方法
方法 | 作用 |
---|---|
join() |
让主进程代码等待子进程代码运行结束再执行 |
current_process |
查看进程号 |
os.getpid() |
查看进程号 |
os.getppid() |
查看父进程进程号 |
p.name |
进程的名字 |
p.terminate() |
杀死子进程 |
p.is_alive() |
判断进程是否存活 |
3.进程间数据隔离
同一台计算机上的多个进程数据上严格意义上的物理隔离(默认情况下),也就是说默认情况下进程之间无法互相传递信息
4.守护进程
守护进程会随着守护的进程结束而立刻结束
方法 | 作用 |
---|---|
p.daemon | 声明p对象生成的子进程是主进程的守护进程 |
5.僵尸进程与孤儿进程
僵尸进程:进程执行完毕后并不会立刻销毁所有的数据,会有一些信息短暂保留下来,这个时候进程会变成僵尸进程
所有的进程都会变成僵尸进程的时刻
孤儿进程:子进程正常运行,父进程意外死亡,操作系统针对孤儿进程会派遣福利院管理
十六、ipc机制与消息队列
ipc:一台计算机上的进程间通行
消息队列Queue:存储数据的地方,公共仓库,所有人都可以存,都可以取
"当台计算机上的消息队列"
from multiprocessing import Queue
q = Queue(3) # 括号内可以指定存储数据的个数
# 往消息队列中存放消息
q.put(1)
print(q.full()) # 判断队列是否已满返回布尔值
q.put(2)
q.put(3)
print(q.full())
# q.put(4) # 程序等在这里了
print(q.get())
print(q.get())
print(q.empty()) # False 判断队列是否为空
print(q.get())
# print(q.get()) # 程序等在这里了长期进入io状态
print(q.get_nowait()) # 直接报错_queue.Empty